home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / cmln0585.arc / BSLP.DOC < prev    next >
Text File  |  1986-02-27  |  67KB  |  2,228 lines

  1.  
  2.                            BSLP BASIC 
  3.  
  4.     INTRODUCTION 
  5.  
  6.          BMLP and BSLP  are  preprocessor  tools for  Microsoft BASIC.
  7.          
  8.          BMLP is a macro language preprocessor. It allows you to write 
  9.          your programs using macros which you define in the program or 
  10.          within macro library text files.  
  11.          
  12.          BSLP  takes  a  source  file  containing  special  structured 
  13.          statements and translates it into a program containing  BASIC 
  14.          statements.  
  15.          
  16.          Using these tools will help you write  more  concise,  better
  17.          structured BASIC programs,  by allowing you to take advantage
  18.          of these features:
  19.          
  20.          - program  with macros  using parameters and subroutines that
  21.            are  maintained in  libraries where they can be accessed by 
  22.            all your programs.  
  23.          
  24.          - write free-form, indented statements without  line  numbers.  
  25.  
  26.          - include statements from many separate files  and  libraries 
  27.            into  a  single  BASIC  program.  (This lets  you write and 
  28.            maintain your programs in small modules.)  
  29.  
  30.          - organize your subroutines into procedures,  each  with  its 
  31.            own descriptive alpha-numeric name.  
  32.  
  33.          - structure  your programming  with multi-line  conditionals,
  34.            loop  and  case   constructs  similar  to  those  found  in 
  35.            programming languages like C and Pascal.  
  36.  
  37.          When using these preprocessors,  please  bear  in  mind  that 
  38.          these versions are written in BASIC and are provided for your 
  39.          use and you are free to modify them in any manner you see fit.  
  40.          
  41.          If you find these tools useful, we have a package called  PPE 
  42.          (Professional Programming Environment) that  includes a super 
  43.          preprocessor   (SLPC)  which  is  written  in  C  for  faster 
  44.          processing  (300-400  lines/min).  It  does  everything  that 
  45.          these  do PLUS a lot more,  like providing a define statement 
  46.          for text substitution and built-in random file handling macro 
  47.          statements.  It comes with a large library of  macros  and  a 
  48.          library manager program.  
  49.          
  50.          If  you have suggestions,  questions,  comments or would like 
  51.          more information about the PPE package, 
  52.          please contact us at:
  53.  
  54.                  Bendorf Associates
  55.                  P.O. Box 5910è                 6006 S. Main
  56.                  Roswell, NM 88201
  57.                  (505) 347-5701
  58.         
  59.          The following is a list  and  brief  abstract of the files on
  60.          this disk:           
  61.  
  62.          Files for BSLP: Basic Structured Language Preprocessor 
  63.  
  64.            BSLP.P . . . . . . . Structured Language Source Text
  65.            BSLP.BAS . . . . . . Microsoft Basic Source Code
  66.            BSLP.DOC . . . . . . Documentation
  67.            BSLP.MSD . . . . . . MS-DOS Compiled Version (.EXE)
  68.            BSLP.CPM . . . . . . CP/M 80 Compiled Version (.COM)
  69.  
  70.          Files for BMLP: Basic Macro Language Preprocessor
  71.  
  72.            BMLP.P . . . . . . . Structured Language Source Text
  73.            BMLP.BAS . . . . . . Microsoft Basic Source Code
  74.            BMLP.DOC . . . . . . Documentation
  75.            BMLP.MSD . . . . . . MS-DOS Compiled Version (.EXE)
  76.            BMLP.CPM . . . . . . CP/M 80 Compiled Version (.COM)
  77.  
  78.          Files for BSLP & BMLP example programs
  79.  
  80.            XFRAME.M . . . . . . Example Program Source Text
  81.            XFRAME.ML  . . . . . Library for XFRAME.M
  82.            BINPUT.M . . . . . . Example Program Source Text
  83.            BINPUT.ML  . . . . . Library for BINPUT.M
  84.  
  85.  
  86. BSLP.BAS
  87.  
  88. 100 DATA   proc...
  89. 101 DATA   prog...
  90. 102 DATA   when...
  91. 103 DATA   unless.
  92. 104 DATA   repeat.
  93. 105 DATA   loop...
  94. 106 DATA   switch.
  95. 107 DATA   case...
  96. 108 DATA   else...
  97. 109 DATA   break..
  98. 110 DATA   endp...
  99. 111 DATA   pend...
  100. 112 DATA   endw...
  101. 113 DATA   endu...
  102. 114 DATA   until..
  103. 115 DATA   endl...
  104. 116 DATA   endc...
  105. 117 PROC.%   = 1
  106. 118 PROG.%   = 2
  107. 119 WHEN.%   = 3
  108. 120 UNLESS.% = 4
  109. 121 REPEAT.% = 5è122 LOOP.%   = 6
  110. 123 SWITCH.% = 7
  111. 124 CASE.%   = 8
  112. 125 ELSE.%   = 9
  113. 126 BREAK.%  = 10
  114. 127 ENDP.%   = 11
  115. 128 PEND.%   = 12
  116. 129 ENDW.%   = 13
  117. 130 ENDU.%   = 14
  118. 131 UNTIL.%  = 15
  119. 132 ENDL.%   = 16
  120. 133 ENDC.%   = 17
  121. 134 DATA 11,12,13,14,15,16,17,17,13,17
  122. 135 DOT$     = "."
  123. 136 DOTS$    = "...."
  124. 137 SKIP$    = " "
  125. 138 SKIP1$   = "  '"
  126. 139 OEXT$    = ".BAS"
  127. 140 IEXT$    = ".P"
  128. 141 EEXT$    = ".E"
  129. 142 INCL$    = ".INC"
  130. 143 TM$      = " ,="
  131. 144 T.FILE$  = "BSLP.$$$"
  132. 145 T.FILE%  = 1
  133. 146 E.FILE%  = 2
  134. 147 I.FILE%  = 3
  135. 148 O.FILE%  = 3
  136. 149 ERRORS%  = 0
  137. 150 KERR%    = 1
  138. 151 LEVELS%  = 0
  139. 152 PUSH%    = 0
  140. 153 NUM%     = 0
  141. 154 STACK.%  = 0
  142. 155 NKEY%    = 17
  143. 156 INCS%    = 1
  144. 157 INC%     = 0
  145. 158 FILE%    = 2
  146. 159 BASIC$   = "restore.resume.return.goto.gosub"
  147. 160 DIM CLOSING%(10)        ' For error messages.
  148. 161 DIM INC$(50)            ' Include file stack.
  149. 162 DIM STACK$(500)
  150. 163 DIM STACK%(500)
  151. 164 DIM NUM.%(500)
  152. 165 DIM KEYWORD.%(99,2)
  153. 166 DIM XN.%(99)
  154. 167 DIM LOOPS%(99)
  155. 168 DIM SWITCH$(10)         ' For the left operand of SWITCH.
  156. 169 DIM KEYWORD$(22)        ' For error messages.
  157. 170 FOR I%=1 TO NKEY%:READ BUF$:TABLE$=TABLE$+BUF$:KEYWORD$(I%)=BUF$:NEXT I%
  158. 171 FOR I%=1 TO 10:READ CLOSING%(I%):NEXT I%
  159. 172 PRINT "BSLP   V1.1B (C) BENDORF ASSOCIATES, 1984-85"
  160. 173 PRINT:GoSub 566
  161. 174 IF NOT(GOOD%) GOTO 177
  162. 175 GoSub 181
  163. 176 GOTO 179è177 IF NOT(I.FILE$<>"") GOTO 179
  164. 178 PRINT"CANNOT OPEN ";I.FILE$
  165. 179 END
  166. 180     'BEGIN
  167. 181 GoSub 194
  168. 182 CLOSE
  169. 183 IF NOT(ERRORS%=0) GOTO 186
  170. 184 KILL E.FILE$:GoSub 463:CLOSE:KILL T.FILE$
  171. 185 GOTO 188
  172. 186 KILL T.FILE$:PRINT E.FILE$;" PRODUCED WITH ";STR$(ERRORS%);" ERROR(S)."
  173. 187 END
  174. 188 IF NOT(ERRORS%>0) GOTO 191
  175. 189 KILL O.FILE$:PRINT O.FILE$;" ABORTED WITH ";STR$(ERRORS%);" ERROR(S)."
  176. 190 GOTO 192
  177. 191 PRINT"<";O.FILE$;"> DONE!"
  178. 192 RETURN
  179. 193     'PASS_1
  180. 194 Open"O",T.FILE%,T.FILE$:Open"O",E.FILE%,E.FILE$:GoSub 290:INC$(INCS%)=I.FILE$
  181. 195 INC%=INC%+1:FILE%=FILE%+1:FILE$=INC$(INC%):Open"I",FILE%,FILE$
  182. 196 GoSub 201:GoSub 275
  183. 197 IF NOT(FILE%=2) GOTO 196
  184. 198 IF NOT(INC%=INCS%) GOTO 195
  185. 199 RETURN
  186. 200     'INPUT-SOURCE
  187. 201 LINE INPUT #FILE%,BUF$
  188. 202 IF NOT(LEN(BUF$)>2) GOTO 226
  189. 203 XLINE$=BUF$:GoSub 232
  190. 204 IF(LEN(BUF$)=0) GOTO 225
  191. 205 INDEX%=0:GoSub 550
  192. 206 IF NOT(RIGHT$(TEXT$,1)=":") GOTO 210
  193. 207 IF(LEN(SBUFF$)>0)THEN GoSub 266
  194. 208 FLAG%=2:LEVEL$=LEFT$(TEXT$,LEN(TEXT$)-1):COMMENT$=SKIP1$+LEVEL$:GoSub 435
  195. 209 GOTO 225
  196. 210 L$=LEFT$(TEXT$,1):KEYWORD%=0
  197. 211 IF(LEN(TEXT$)<4 OR LEN(TEXT$)>6) GOTO 213
  198. 212 C.$=TEXT$:GoSub 606:KEYS$=C.$+DOTS$:KEYWORD%=INSTR(1,TABLE$,LEFT$(KEYS$,7)):KEYWORD%=(KEYWORD%+6)\7
  199. 213 IF NOT(KEYWORD%>0) GOTO 217
  200. 214 IF(LEN(SBUFF$)>0)THEN GoSub 266
  201. 215 GoSub 269
  202. 216 GOTO 225
  203. 217 IF NOT(L$="-") GOTO 220
  204. 218 GoSub 588
  205. 219 GOTO 225
  206. 220 IF NOT(L$="+") GOTO 224
  207. 221 IF(LEN(SBUFF$)>0)THEN GoSub 266
  208. 222 GoSub 581
  209. 223 GOTO 225
  210. 224 GoSub 251
  211. 225 NERR%=NERR%+1:PRINT #E.FILE%,STR$(NERR%);SKIP$;XLINE$
  212. 226 IF NOT(EOF(FILE%)) GOTO 201
  213. 227 CLOSE #FILE%:FILE%=FILE%-1
  214. 228 IF(SBUFF$="") GOTO 230
  215. 229 BUF$="":CFLAG%=0:GoSub 251
  216. 230 RETURN
  217. 231     'STRIPè232 Z1%=INSTR(BUF$,CHR$(9)):Z2%=INSTR(BUF$,CHR$(10))
  218. 233 WHILE (Z1% OR Z2%)
  219. 234 IF Z1% THEN MID$(BUF$,Z1%,1)=" "
  220. 235 IF Z2% THEN MID$(BUF$,Z2%,1)=" "
  221. 236 Z1%=INSTR(BUF$,CHR$(9)):Z2%=INSTR(BUF$,CHR$(10)):WEND
  222. 237 Z1%=1:WHILE (MID$(BUF$,Z1%,1)=" " AND Z1%<LEN(BUF$)):Z1%=Z1%+1:WEND
  223. 238 Z2%=LEN(BUF$):WHILE (MID$(BUF$,Z2%,1)=" " AND Z2%>1):Z2%=Z2%-1:WEND
  224. 239 IF NOT(Z2%<Z1%) GOTO 242
  225. 240 BUF$=""
  226. 241 GOTO 245
  227. 242 BUF$=MID$(BUF$,Z1%,Z2%-Z1%+1)
  228. 243 IF NOT(LEN(BUF$)>0) GOTO 245
  229. 244 IF(LEFT$(BUF$,1)="'" OR LEFT$(BUF$,3)="REM" OR BUF$=STRING$(LEN(BUF$),32))THEN BUF$=""
  230. 245 LN.%=LEN(BUF$):CFLAG%=0
  231. 246 IF(LN.%=0) GOTO 249
  232. 247 CFLAG%=(RIGHT$(BUF$,1)="|")
  233. 248 IF(CFLAG%)THEN BUF$=LEFT$(BUF$,LN.%-1):LN.%=LEN(BUF$)
  234. 249 RETURN
  235. 250     'OUT_PUT
  236. 251 IF NOT(CFLAG%=0) GOTO 259
  237. 252 IF NOT(LEN(SBUFF$)>0) GOTO 257
  238. 253 IF NOT(LEN(SBUFF$+BUF$)<=250) GOTO 256
  239. 254 BUF$=SBUFF$+BUF$:SBUFF$=""
  240. 255 GOTO 257
  241. 256 GoSub 266
  242. 257 PBUF$=BUF$:FLAG%=3:GoSub 435
  243. 258 GOTO 263
  244. 259 IF NOT(LEN(SBUFF$+BUF$)<=250) GOTO 262
  245. 260 SBUFF$=SBUFF$+BUF$+":"
  246. 261 GOTO 263
  247. 262 GoSub 266:PBUF$=BUF$:GoSub 435
  248. 263 BUF$=""
  249. 264 RETURN
  250. 265     'DUMP
  251. 266 PBUF$=LEFT$(SBUFF$,LEN(SBUFF$)-1):FLAG%=3:GoSub 435:SBUFF$="":CFLAG%=0
  252. 267 RETURN
  253. 268     'KEYWORDS
  254. 269 KERR%=NERR%+1
  255. 270 ON KEYWORD% GOTO 302,319,328,354,364,364
  256. 271 ON KEYWORD%-6 GOTO 405,411,331,421,309,322,343
  257. 272 ON KEYWORD%-13 GOTO 357,371,381,428
  258. 273 RETURN
  259. 274     'POP_ERRORS
  260. 275 KER%=KERR%:KWDS%=KEYWORD%:GoSub 293
  261. 276 while KEYWORD%>0
  262. 277 GoSub 282
  263. 278 wend
  264. 279 GoSub 290:KEYWORD%=KWDS%:KERR%=KER%
  265. 280 RETURN
  266. 281     'RESOLVE-ERRORS
  267. 282 IF(KEYWORD%<11)THEN KEYWORD%=CLOSING%(KEYWORD%)
  268. 283 EBUF$=KEYWORD$(KEYWORD%):GoSub 603
  269. 284 IF NOT(KEYWORD%=ENDW.% OR KEYWORD%=ENDU.% OR KEYWORD%=ENDC.%) GOTO 287
  270. 285 IF(KEYWORD%=ENDC.%)THEN GoSub 293
  271. 286 GoSub 293è287 GoSub 293
  272. 288 RETURN
  273. 289     'PUSH
  274. 290 PUSH%=PUSH%+1:KEYWORD.%(PUSH%,0)=KEYWORD%:KEYWORD.%(PUSH%,1)=KERR%:KEYWORD.%(PUSH%,2)=LEVEL%
  275. 291 RETURN
  276. 292     'POP
  277. 293 IF NOT(PUSH%>0) GOTO 296
  278. 294 KEYWORD%=KEYWORD.%(PUSH%,0):KERR%=KEYWORD.%(PUSH%,1):LEVEL%=KEYWORD.%(PUSH%,2):PUSH%=PUSH%-1
  279. 295 GOTO 297
  280. 296 LEVEL%=-1:KEYWORD%=-1
  281. 297 RETURN
  282. 298     'LEVEL
  283. 299 LEVELS%=LEVELS%+1:LEVEL%=LEVELS%:TK%=LEVEL%:GoSub 290
  284. 300 RETURN
  285. 301     '_PROC
  286. 302 GoSub 275:GoSub 290:GoSub 550
  287. 303 IF NOT(LEN(TEXT$)>0) GOTO 306
  288. 304 COMMENT$=SKIP1$+TEXT$:LPROC$=TEXT$:FLAG%=2:LEVEL$=TEXT$:GoSub 435
  289. 305 GOTO 307
  290. 306 EBUF$="procedure name":GoSub 603
  291. 307 RETURN
  292. 308     '_ENDP
  293. 309 GoSub 293
  294. 310 WHILE KEYWORD%<>PROC.% AND KEYWORD%>0
  295. 311 GoSub 282
  296. 312 WEND
  297. 313 IF NOT(KEYWORD%=PROC.%) GOTO 316
  298. 314 FLAG%=3:PBUF$="RETURN":GoSub 435
  299. 315 GOTO 317
  300. 316 EBUF$=KEYWORD$(PROC.%):GoSub 603
  301. 317 RETURN
  302. 318     '_PROG
  303. 319 PROG..%=1
  304. 320 RETURN
  305. 321     '_PEND
  306. 322 IF NOT(PROG..%=1) GOTO 325
  307. 323 FLAG%=3:PBUF$="END":GoSub 435
  308. 324 GOTO 326
  309. 325 EBUF$=KEYWORD$(PROG.%):GoSub 603
  310. 326 RETURN
  311. 327     '_WHEN
  312. 328 GoSub 299:GoSub 299:FLAG%=1:GoSub 435
  313. 329 RETURN
  314. 330     '_ELSE
  315. 331 GoSub 293
  316. 332 IF NOT(KEYWORD%=WHEN.%) GOTO 340
  317. 333 F.%=LEVEL%:GoSub 293:T.%=LEVEL%:TK%=T.%:FLAG%=4:PBUF$="GOTO ":GoSub 435:XN%=XN%+1:XN.%(XN%)=F.%:GoSub 550:C.$=TEXT$:GoSub 606
  318. 334 IF NOT(C.$="when" OR C.$="unless") GOTO 337
  319. 335 GoSub 299:F.%=LEVEL%:FLAG%=ABS(C.$="when"):GoSub 435:GoSub 293
  320. 336 GOTO 338
  321. 337 F.%=0
  322. 338 KEYWORD%=WHEN.%:LEVEL%=T.%:GoSub 290:LEVEL%=F.%:GoSub 290
  323. 339 GOTO 341
  324. 340 GoSub 290:EBUF$=KEYWORD$(WHEN.%):GoSub 603
  325. 341 RETURNè342     '_ENDW
  326. 343 GoSub 293
  327. 344 IF NOT(KEYWORD%=WHEN.%) GOTO 347
  328. 345 F.%=LEVEL%:GoSub 293:T.%=LEVEL%:GoSub 350
  329. 346 GOTO 348
  330. 347 GoSub 290:EBUF$=KEYWORD$(WHEN.%):GoSub 603
  331. 348 RETURN
  332. 349     'POPOFF
  333. 350 IF(F.%>0)THEN XN%=XN%+1:XN.%(XN%)=F.%
  334. 351 IF(T.%>0)THEN XN%=XN%+1:XN.%(XN%)=T.%
  335. 352 RETURN
  336. 353     '_UNLESS
  337. 354 GoSub 299:GoSub 299:FLAG%=0:GoSub 435
  338. 355 RETURN
  339. 356     '_ENDU
  340. 357 GoSub 293
  341. 358 IF NOT(KEYWORD%=UNLESS.%) GOTO 361
  342. 359 F.%=LEVEL%:GoSub 293:T.%=LEVEL%:GoSub 350
  343. 360 GOTO 362
  344. 361 GoSub 290:EBUF$=KEYWORD$(UNLESS.%):GoSub 603
  345. 362 RETURN
  346. 363     '_REPEAT
  347. 364 GoSub 550:C.$=TEXT$:GoSub 606:LOOP%=LOOP%+1:GoSub 299:XN%=XN%+1:XN.%(XN%)=LEVEL%
  348. 365 IF NOT(C.$<>"when" AND C.$<>"unless") GOTO 368
  349. 366 LOOPS%(LOOP%)=LEVEL%
  350. 367 GOTO 369
  351. 368 LOOPS%(LOOP%)=LEVEL%*-1:GoSub 293:LEVEL%=LEVEL%*-1:GoSub 290:GoSub 299:FLAG%=ABS(C.$="when"):GoSub 435
  352. 369 RETURN
  353. 370     '_UNTIL
  354. 371 IF NOT(LOOP%>0) GOTO 378
  355. 372 GoSub 293
  356. 373 IF NOT(KEYWORD%=REPEAT.% OR KEYWORD%=LOOP.%) GOTO 376
  357. 374 LOOP%=LOOP%-1:TK%=LOOPS%(LOOP%+1):FLAG%=1:GoSub 435
  358. 375 GOTO 377
  359. 376 GoSub 290:EBUF$=KEYWORD$(REPEAT.%):GoSub 603
  360. 377 GOTO 379
  361. 378 EBUF$=KEYWORD$(REPEAT.%):GoSub 603
  362. 379 RETURN
  363. 380     '_ENDL
  364. 381 IF NOT(LOOP%>0) GOTO 402
  365. 382 GoSub 293
  366. 383 IF NOT(KEYWORD%=REPEAT.% OR KEYWORD%=LOOP.%) GOTO 400
  367. 384 GoSub 550:C.$=TEXT$:GoSub 606:LOOP%=LOOP%-1
  368. 385 IF NOT(LOOPS%(LOOP%+1)>0) GOTO 392
  369. 386 TK%=LOOPS%(LOOP%+1)
  370. 387 IF NOT(C.$="when" OR C.$="unless") GOTO 390
  371. 388 FLAG%=ABS(C.$="when"):GoSub 435
  372. 389 GOTO 391
  373. 390 EBUF$=KEYWORD$(WHEN.%):GoSub 603
  374. 391 GOTO 399
  375. 392 TK%=LOOPS%(LOOP%+1)*-1
  376. 393 IF NOT(C.$="when" OR C.$="unless") GOTO 396
  377. 394 FLAG%=ABS(C.$="when")
  378. 395 GOTO 397
  379. 396 FLAG%=4:PBUF$="GOTO "è397 GoSub 435
  380. 398 F.%=LEVEL%:GoSub 293:T.%=LEVEL%:GoSub 350
  381. 399 GOTO 401
  382. 400 GoSub 290:EBUF$=KEYWORD$(LOOP.%):GoSub 603
  383. 401 GOTO 403
  384. 402 EBUF$=KEYWORD$(LOOP.%):GoSub 603
  385. 403 RETURN
  386. 404     '_SWITCH
  387. 405 IF NOT(C.LN.%>0) GOTO 408
  388. 406 GoSub 299:GoSub 299:GoSub 299:SWITCH$(SWITCH%+1)=COND$:SWITCH%=SWITCH%+1
  389. 407 GOTO 409
  390. 408 EBUF$="operand":GoSub 603
  391. 409 RETURN
  392. 410     '_CASE
  393. 411 GoSub 293
  394. 412 IF NOT(KEYWORD%=SWITCH.% AND SWITCH%>0) GOTO 418
  395. 413 IF NOT(C.LN.%>0) GOTO 416
  396. 414 XN%=XN%+1:XN.%(XN%)=LEVEL%:GoSub 299:FLAG%=4:PBUF$="IF("+SWITCH$(SWITCH%)+"<>"+COND$+") GOTO ":GoSub 435
  397. 415 GOTO 417
  398. 416 EBUF$="operand":GoSub 603
  399. 417 GOTO 419
  400. 418 GoSub 290:EBUF$=KEYWORD$(SWITCH.%):GoSub 603
  401. 419 RETURN
  402. 420     '_BREAK
  403. 421 GoSub 293
  404. 422 IF NOT(KEYWORD%=SWITCH.%) GOTO 425
  405. 423 F.%=LEVEL%:GoSub 293:T.%=LEVEL%:TK%=T.%:FLAG%=4:PBUF$="GOTO ":GoSub 435:KEYWORD%=SWITCH.%:LEVEL%=T.%:GoSub 290:LEVEL%=F.%:GoSub 290
  406. 424 GOTO 426
  407. 425 GoSub 290:EBUF$=KEYWORD$(SWITCH.%):GoSub 603
  408. 426 RETURN
  409. 427     '_ENDC
  410. 428 GoSub 293
  411. 429 IF NOT(KEYWORD%=SWITCH.%) GOTO 432
  412. 430 F.%=LEVEL%:GoSub 293:T.%=LEVEL%:GoSub 293:GoSub 350:SWITCH%=SWITCH%-1
  413. 431 GOTO 433
  414. 432 GoSub 290:EBUF$=KEYWORD$(SWITCH.%):GoSub 603
  415. 433 RETURN
  416. 434     'OUT_LINE
  417. 435 IF NOT(FLAG%<2 AND C.LN.%=0) GOTO 438
  418. 436 EBUF$="condition":GoSub 603
  419. 437 GOTO 453
  420. 438 NUM%=NUM%+1:OFFSET%=1
  421. 439 IF(FLAG%<2 OR FLAG%>3)THEN LEVEL$=STR$(TK%):MID$(LEVEL$,1,1)="@"
  422. 440 IF(FLAG%<>0) GOTO 443
  423. 441 PBUF$="IF("+COND$+") GOTO "+LEVEL$
  424. 442 GOTO 451
  425. 443 IF(FLAG%<>1) GOTO 446
  426. 444 PBUF$="IF NOT("+COND$+") GOTO "+LEVEL$
  427. 445 GOTO 451
  428. 446 IF(FLAG%<>2) GOTO 449
  429. 447 GoSub 459
  430. 448 GOTO 451
  431. 449 IF(FLAG%<>4) GOTO 451
  432. 450 PBUF$=PBUF$+LEVEL$
  433. 451 PRINT #T.FILE%,RIGHT$(STR$(NUM%),LEN(STR$(NUM%))-1);SKIP$;PBUF$;COMMENT$è452 IF(XN%>0 AND FLAG%<>2)THEN GoSub 456
  434. 453 COMMENT$="":PBUF$="":LEVEL$=""
  435. 454 RETURN
  436. 455     'STORE_IT
  437. 456 OFFSET%=0:FOR I%=1 TO XN%:LEVEL$=STR$(XN.%(I%)):MID$(LEVEL$,1,1)="@":GoSub 459:NEXT I%:XN%=0
  438. 457 RETURN
  439. 458     'STACK_IT
  440. 459 STACK.%=STACK.%+1:STACK%(STACK.%)=NUM%+OFFSET%:STACK$(STACK.%)=LEVEL$:IF(COMPIL%)THEN NUM.%(STACK.%)=NUM%+OFFSET%
  441. 460 OFFSET%=0
  442. 461 RETURN
  443. 462     'PASS_2
  444. 463 GoSub 534:OFFSET%=2:Open"I",T.FILE%,T.FILE$:Open"O",O.FILE%,O.FILE$
  445. 464 LINE INPUT #T.FILE%,BUF$:GoSub 468
  446. 465 IF NOT(EOF(T.FILE%)) GOTO 464
  447. 466 RETURN
  448. 467     'PROCESS_1
  449. 468 INDEX%=0:ONFLAG%=0:LN.%=LEN(BUF$):GoSub 550:IF(COMPIL%)THEN GoSub 477
  450. 469 while FIRST%<=LEN(BUF$)
  451. 470 IF(LEN(TEXT$)>7 OR LEN(TEXT$)<2 OR VAL(TEXT$)>0) GOTO 472
  452. 471 GoSub 491
  453. 472 GoSub 550
  454. 473 wend
  455. 474 PRINT #O.FILE%,BUF$
  456. 475 RETURN
  457. 476     'COMPIL
  458. 477 TEXT%=VAL(TEXT$):HIGH%=STACK.%+1:LOW%=0
  459. 478 IF(TEXT%<NUM.%(1) OR TEXT%>NUM.%(STACK.%)) GOTO 488
  460. 479 while((HIGH%-LOW%)>1):I%=(HIGH%+LOW%)\2
  461. 480 IF NOT(NUM.%(I%)=TEXT%) GOTO 483
  462. 481 TEXT%=-1:LOW%=HIGH%
  463. 482 GOTO 487
  464. 483 IF NOT(NUM.%(I%)<TEXT%) GOTO 486
  465. 484 LOW%=I%
  466. 485 GOTO 487
  467. 486 HIGH%=I%
  468. 487 wend
  469. 488 IF(TEXT%>0)THEN BUF$=SPACE$(LEN(TEXT$)+1)+COND$
  470. 489 RETURN
  471. 490     'FIND_IT
  472. 491 C.$=TEXT$:GoSub 606
  473. 492 IF NOT(C.$="on") GOTO 495
  474. 493 ONFLAG%=-1
  475. 494 GOTO 502
  476. 495 IF NOT(LEN(C.$)>3) GOTO 502
  477. 496 IF(INSTR(BASIC$,C.$)=0 OR COLN%) GOTO 502
  478. 497 GoSub 550:I$=LEFT$(TEXT$,1)
  479. 498 IF(I$="@" OR LEN(TEXT$)<>4) GOTO 500
  480. 499 C.$=TEXT$:GoSub 606:IF(C.$="else")THEN RETURN
  481. 500 IF(I$="0" AND ONFLAG%) GOTO 502
  482. 501 IF(ONFLAG%)THEN GoSub 504 ELSE GoSub 512
  483. 502 RETURN
  484. 503     'ON_FLAG
  485. 504 OFFSET%=1
  486. 505 while(FIRST%<=LEN(BUF$))
  487. 506 IF(TEXT$<>"")THEN GoSub 512è507 GoSub 550
  488. 508 wend
  489. 509 OFFSET%=2
  490. 510 RETURN
  491. 511     'SEARCH
  492. 512 HIGH%=STACK.%+1:LOW%=0:FIND%=-1
  493. 513 while((HIGH%-LOW%)>1):I%=(HIGH%+LOW%)\2
  494. 514 IF NOT(STACK$(I%)=TEXT$) GOTO 517
  495. 515 FIND%=STACK%(I%):LOW%=HIGH%
  496. 516 GOTO 521
  497. 517 IF NOT(STACK$(I%)<TEXT$) GOTO 520
  498. 518 LOW%=I%
  499. 519 GOTO 521
  500. 520 HIGH%=I%
  501. 521 wend
  502. 522 IF NOT(FIND%>0) GOTO 525
  503. 523 GoSub 529
  504. 524 GOTO 527
  505. 525 IF NOT(TEXT$<>"") GOTO 527
  506. 526 ERRORS%=ERRORS%+1:PRINT"MISSING LABEL (";TEXT$;")"
  507. 527 RETURN
  508. 528     'STUFF_IT
  509. 529 NUM$=STR$(FIND%):SP$="":L$=LEFT$(BUF$,FIRST%-OFFSET%)
  510. 530 IF(LEFT$(COND$,1)<>" " AND LEFT$(COND$,1)<>":" AND ONFLAG%=0)THEN SP$=" "
  511. 531 BUF$=L$+NUM$+SP$+COND$:INDEX%=LEN(L$)+LEN(NUM$):LN.%=LEN(BUF$)
  512. 532 RETURN
  513. 533     'SORT
  514. 534 PT.%=STACK.%:while (PT.%>0):PT.%=PT.%\2
  515. 535 IF NOT(PT.%>0) GOTO 547
  516. 536 JT.%=1:KT.%=STACK.%-PT.%:while (JT.%<=KT.%):LT.%=JT.%:CT.%=LT.%+PT.%
  517. 537 while (LT.%>0 AND STACK$(LT.%)>=STACK$(CT.%))
  518. 538 SWAP STACK$(LT.%),STACK$(CT.%):SWAP STACK%(LT.%),STACK%(CT.%)
  519. 539 CT.%=LT.%:LT.%=LT.%-PT.%:LT.%=LT.%*(1+(LT.%<0))
  520. 540 wend
  521. 541 IF NOT(COMPIL%) GOTO 546
  522. 542 LT.%=JT.%:CT.%=LT.%+PT.%
  523. 543 while (LT.%>0 AND NUM.%(LT.%)>=NUM.%(CT.%))
  524. 544 SWAP NUM.%(LT.%),NUM.%(CT.%):CT.%=LT.%:LT.%=LT.%-PT.%:LT.%=LT.%*(1+(LT.%<0))
  525. 545 wend
  526. 546 JT.%=JT.%+1:wend
  527. 547 wend
  528. 548 RETURN
  529. 549     'PARSER
  530. 550 C.LN.%=0:I.%=0:COLN%=0:II%=32:TEXT%=0:COND$="":TRM$=TM$+CHR$(58*ABS(INDEX%>0))
  531. 551 while(INSTR(TRM$,CHR$(II%))>0):INDEX%=INDEX%+1:IF(INDEX%<=LEN(BUF$))THEN II%=ASC(MID$(BUF$,INDEX%,1)) ELSE II%=7
  532. 552 wend:FIRST%=INDEX%
  533. 553 while(II%<>32 AND II%<>7)
  534. 554 IF NOT(INSTR(TRM$,CHR$(II%))>0 AND TEXT%=0) GOTO 557
  535. 555 COLN%=(CHR$(II%)=":"):I.%=1:II%=32
  536. 556 GOTO 562
  537. 557 IF NOT(II%=34 OR II%=40 OR II%=41) GOTO 560
  538. 558 IF(II%=34)THEN INDEX%=INSTR(INDEX%+1,BUF$,CHR$(34))
  539. 559 IF(II%=40)THEN TEXT%=TEXT%+1 ELSE IF(II%=41)THEN TEXT%=TEXT%-1
  540. 560 INDEX%=INDEX%+1:IF(INDEX%<=LEN(BUF$))THEN II%=ASC(MID$(BUF$,INDEX%,1)) ELSE II%=7
  541. 561 IF(II%=32 AND TEXT%<>0) GOTO 560è562 wend
  542. 563 TEXT$=MID$(BUF$,FIRST%,INDEX%-FIRST%):IF(LEN(BUF$)>INDEX%)THEN COND$=RIGHT$(BUF$,(LEN(BUF$)-INDEX%)+I.%):C.LN.%=LEN(COND$)
  543. 564 RETURN
  544. 565     'FILENAMES
  545. 566 LINE INPUT"INPUT FILE [.P]:",I.FILE$
  546. 567 IF(I.FILE$="") GOTO 579
  547. 568 COMPIL%=(INSTR(I.FILE$,"/")>0)
  548. 569 IF(COMPIL%)THEN I.FILE$=LEFT$(I.FILE$,LEN(I.FILE$)-1)
  549. 570 IF(INSTR(I.FILE$,DOT$)=0)THEN I.FILE$=I.FILE$+IEXT$
  550. 571 LK.$=I.FILE$:LK.%=I.FILE%:GoSub 614:I.FILE%=LK.%:GOOD%=(I.FILE%<>FALSE%)
  551. 572 IF(GOOD%=FALSE%) GOTO 579
  552. 573 I%=INSTR(1,I.FILE$,DOT$)
  553. 574 IF(I%=0)THEN I%=LEN(I.FILE$)+1
  554. 575 E.FILE$=LEFT$(I.FILE$,I%-1):LINE INPUT"OUTPUT FILE [.BAS]:",O.FILE$
  555. 576 IF(O.FILE$="")THEN O.FILE$=E.FILE$
  556. 577 IF(INSTR(O.FILE$,DOT$)=0)THEN O.FILE$=O.FILE$+OEXT$
  557. 578 IF(INSTR(E.FILE$,DOT$)=0)THEN E.FILE$=E.FILE$+EEXT$
  558. 579 RETURN
  559. 580     'INCLUDES
  560. 581 GoSub 599
  561. 582 IF NOT(FILE.%>0) GOTO 585
  562. 583 Open"I",FILE.%,FILE$:FILE%=FILE.%
  563. 584 GOTO 586
  564. 585 EBUF$="include "+FILE$:GoSub 603
  565. 586 RETURN
  566. 587     'SUBROUTINE
  567. 588 GoSub 599
  568. 589 IF NOT(FILE.%>0) GOTO 596
  569. 590 TEXT%=0
  570. 591 while(TEXT%<INCS%)
  571. 592 TEXT%=TEXT%+1:IF(FILE$=INC$(TEXT%))THEN TEXT%=INCS%+1
  572. 593 wend
  573. 594 IF(TEXT%=INCS%)THEN INCS%=INCS%+1:INC$(INCS%)=FILE$
  574. 595 GOTO 597
  575. 596 EBUF$="include "+FILE$:GoSub 603
  576. 597 RETURN
  577. 598     'FILES
  578. 599 FILE$=RIGHT$(TEXT$,LEN(TEXT$)-1):IF(INSTR(FILE$,DOT$)=0)THEN FILE$=FILE$+INCL$
  579. 600 FILE.%=FILE%+1:LK.$=FILE$:LK.%=FILE.%:GoSub 614:FILE.%=LK.%
  580. 601 RETURN
  581. 602     'ERRORS
  582. 603 ERRORS%=ERRORS%+1:EBUF$="ERR#"+STR$(ERRORS%)+" MISSING ("+EBUF$+") PROC <"+LPROC$+">":EBUF$=EBUF$+" AT"+STR$(KERR%):PRINT EBUF$:PRINT #E.FILE%,EBUF$
  583. 604 RETURN
  584. 605     '_Fold
  585. 606 f.0%=1
  586. 607 while(f.0%<=LEN(C.$))
  587. 608 f.2%=ASC(MID$(C.$,f.0%,1))
  588. 609 f.2%=f.2%+(32*ABS(f.2%>64 AND f.2%<91))
  589. 610 MID$(C.$,f.0%,1)=CHR$(f.2%):f.0%=f.0%+1
  590. 611 wend
  591. 612 RETURN
  592. 613     '_Lookup
  593. 614 OPEN"R",LK.%,LK.$:L.K!=LOF(LK.%):CLOSE LK.%
  594. 615 IF(L.K!<1)THEN LK.%=0:KILL LK.$
  595. 616 RETURNè
  596.  
  597. BSLP.DOC
  598.  
  599.  
  600.  
  601.    BSLP Version 1.0B                                                Page 1.0
  602.  
  603.    Table of Contents
  604.  
  605.         BSLP: Basic Structured Language Preprocessor......... 1.1
  606.               Functions...................................... 1.1
  607.               Invocation..................................... 1.1
  608.               Defaults....................................... 1.1
  609.               Option (/)..................................... 1.1
  610.               Structure Keywords............................. 1.1
  611.                    PROG / PEND............................... 1.2
  612.                    PROC / ENDP............................... 1.2
  613.                    REPEAT / UNTIL............................ 1.3
  614.                    LOOP / ENDL............................... 1.3
  615.                    WHEN / ELSE / ENDW........................ 1.4
  616.                    UNLESS / ENDU............................. 1.4
  617.                    SWITCH / CASE / BREAK / ENDC.............. 1.5
  618.               Error Messages................................. 2.1
  619.                    Structure Related Error Handling.......... 2.1
  620.                    Structure Related Error Messages.......... 2.1
  621.               Included Files (+-)............................ 3.1
  622.  
  623.       Notice:
  624.              Delimiter conventions used in this documentation
  625.              are:
  626.                  <> denotes required information
  627.                  [] denotes optional information
  628.  
  629.  
  630.                                                               
  631.  
  632.  
  633.  
  634.    BSLP Version 1.0B                                                Page 1.1
  635.  
  636.    BSLP - Basic Structured Language Preprocessor
  637.  
  638.  
  639.  
  640.     Function:
  641.  
  642.         BSLP   translates   source  text  written  in  BSLP  structure
  643.         language to standard BASIC code.  BSLP  is  a  BASIC  language
  644.         version  of  the PPE structure translater. It is slow but very
  645.         usable,  and  has  served  well  as  a  tool   for   prototype
  646.         extensions  to the structure language. BSLP is written in BSLP
  647.         structure language and should be a useful learning tool.
  648.  
  649.  
  650.     Invocation:
  651.  
  652.         Entering 'BSLP' at the DOS prompt  will  envoke  the  compiled
  653.         version  (.EXE)  of  BSLP.  The (.BAS) version will have to be
  654.         run using the interpreter by entering  'BASICA  BSLP'  at  the
  655.         DOS  prompt. BSLP will then prompt for the input file name and
  656.         the  output  file  name.  The  default  for  the  input   file
  657.         extension  is  '.P',  and  the  default  for  the  output file
  658.         extension is '.BAS'. The slash (/) following  the  input  file
  659.         name  will cause all non-referenced line numbers to be deleted
  660.         from the output file (.BAS). This allows  a  smaller  compiled
  661.         (.EXE) program.
  662.  
  663.  
  664.     Hints and Restrictions:
  665.  
  666.         Structure  keywords  are  not  case or position sensitive, and
  667.         they must (except for spaces and tabs) be the first  words  on
  668.         a  line.  Do  NOT use comments on the same line with keywords.
  669.         The vertical bar (|) may be use to provide line  continuation.
  670.         Continued  lines  will  be  appended,  separating  them with a
  671.         colon (:).
  672.  
  673.  
  674.     Structure Keywords:
  675.  
  676.         PROG / PEND
  677.  
  678.         PROC <label> / ENDP
  679.  
  680.         REPEAT / UNTIL <condition>
  681.  
  682.         LOOP [<when/unless> <condition>] / ENDL [<when/unless> <condition>]
  683.  
  684.         WHEN <condition> / ELSE [<when/unless> <condition>] / ENDW
  685. è        UNLESS <condition> / ENDU
  686.  
  687.         SWITCH <left operand> / CASE <right operand> / BREAK / ENDC
  688.  
  689.  
  690.  
  691.  
  692.  
  693.    BSLP - Basic Structured Language Preprocessor                    Page 1.1
  694.  
  695.  
  696.  
  697.    BSLP Version 1.0B                                                Page 1.2
  698.  
  699.     Structure Keyword Definitions and Usage:
  700.  
  701.     PROG / PEND
  702.  
  703.         'PROG'  identifies  the  main  controlling  procedure   in   a
  704.         program.  'PEND'  identifies the end of the main procedure and
  705.         causes an "END" BASIC keyword to be generated.
  706.  
  707.     Usage:
  708.  
  709.            PROG Calculate               <----------+
  710.                gosub process_one                   | Main
  711.                gosub process_two                   | Procedure
  712.            PEND                         <----------+
  713.  
  714.  
  715.     PROC <label> / ENDP
  716.  
  717.         'PROC' defines the beginning of a procedure  subroutine  using
  718.         a  label  that  may be referenced by name (e.g. 'GOSUB label')
  719.         from any other procedure in the same  program.  'ENDP'  closes
  720.         the  matching  'PROC'  and  terminates  the  procedure  with a
  721.         "RETURN" BASIC keyword. Procedures can not be nested.
  722.  
  723.     Usage:
  724.  
  725.            PROC Test_Out                <----------+
  726.                when status = test                  | Subroutine
  727.                    gosub test_it                   | Procedure
  728.                endw                                |
  729.            ENDP                         <----------+
  730.  
  731.     *Note:
  732.         A label-name immediately followed by a colon (:) may  be  used
  733.         to identify a label without a procedure statement:
  734.  
  735.            e.g...  ERRORTRAP:
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748. è
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.    Structure Keyword Definitions and Usage                          Page 1.2
  757.  
  758.  
  759.  
  760.    BSLP Version 1.0B                                                Page 1.3
  761.  
  762.     REPEAT / UNTIL <condition>
  763.  
  764.         'REPEAT'  defines the top of a conditional loop structure. The
  765.         matching 'UNTIL' defines the bottom  of  the  loop  where  the
  766.         terminating  condition  is tested. The loop is terminated when
  767.         the condition evaluates true.
  768.  
  769.     Usage:
  770.  
  771.            REPEAT                       <----------+
  772.                index = index + 1                   | Loop
  773.                gosub Index_task                    | Structure
  774.            UNTIL index = task.count     <condition-+
  775.  
  776.  
  777.     LOOP [<when/unless> <condition>] / ENDL [<when/unless> <condition>]
  778.  
  779.         'LOOP' defines the top of a loop structure that will  allow  a
  780.         condition  to  be  tested  at  the  top  and  or at the bottom
  781.         matching 'ENDL'. At  the  top  'WHEN'  evaluates  for  a  true
  782.         condition  to  continue  into the loop structure, and 'UNLESS'
  783.         evaluates for a true condition to branch around the  loop.  At
  784.         the  bottom  'WHEN' evaluates for a true condition to exit the
  785.         loop, and 'UNLESS' evaluates for a true condition to  continue
  786.         the  loop. One condition (top or bottom) is required, but both
  787.         may be use.
  788.  
  789.     Usage:
  790.  
  791.            LOOP                         <----------+
  792.                index = index + 1                   | Loop
  793.                gosub Index_task                    | Structure
  794.            ENDL unless index < task     <condition-+
  795.  
  796.            LOOP when index < task       <condition-+
  797.                index = index + 1                   | Loop
  798.                gosub Index_task                    | Structure
  799.            ENDL                         <----------+
  800.  
  801.            LOOP unless index >= task    <condition-+
  802.                index = index + 1                   | Loop
  803.                gosub Index_task                    | Structure
  804.            ENDL when index >= task      <condition-+
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811. è
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.    Structure Keyword Definitions and Usage                          Page 1.3
  820.  
  821.  
  822.  
  823.    BSLP Version 1.0B                                                Page 1.4
  824.  
  825.     WHEN <condition> / ELSE [<when/unless> <condition>] / ENDW
  826.  
  827.         'WHEN-ELSE-ENDW'  provides  for  multiple   line   conditional
  828.         constructs,  with  no limit on the range or depth of level and
  829.         no limit on the number of 'ELSE' statements used. 'ELSE  WHEN'
  830.         defines  the  "ELSE-IF"  construct,  and 'ELSE UNLESS' defines
  831.         the  "ELSE-IF-NOT"  construct.  'ENDW'  closes  the   matching
  832.         'WHEN' and terminates to the next outer level of processing.
  833.  
  834.     Usage:
  835.  
  836.            WHEN method = manual          IF
  837.                goSub Keyboard                THEN
  838.            ELSE WHEN method = auto       ELSE IF
  839.                goSub Process                 THEN
  840.            ELSE UNLESS method = null     ELSE IF NOT
  841.                goSub Process_End             THEN
  842.            ELSE                          ELSE
  843.                goSub End_Process             THEN
  844.            ENDW
  845.  
  846.  
  847.     UNLESS <condition> / ENDU
  848.  
  849.         'UNLESS'  defines  a  "DO  WHEN NOT TRUE" construct and 'ENDU'
  850.         closes the matching 'UNLESS' and terminates to the next  outer
  851.         level of processing.
  852.  
  853.     Usage:
  854.  
  855.            UNLESS abort = true           IF NOT
  856.                gosub Continue                THEN
  857.            ENDU
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874. è
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.    Structure Keyword Definitions and Usage                          Page 1.4
  883.  
  884.  
  885.  
  886.    BSLP Version 1.0B                                                Page 1.5
  887.  
  888.     SWITCH <left operand> / CASE <right operand> / BREAK / ENDC
  889.  
  890.         'SWITCH-CASE-ENDC'   provides   an   "ON   CONDITION  PROCESS"
  891.         construct. 'SWITCH' defines the operand on the  left  side  of
  892.         the  equal  sign  and  'CASE' defines the operand on the right
  893.         side. There is no limit on the  number  of  'CASE'  statements
  894.         within   a  procedure.  When  a  'SWITCH=CASE'  is  true,  the
  895.         instructions following that 'CASE' are processed,  and  unless
  896.         a  'BREAK' statement is used, processing will continue through
  897.         to the next  'CASE'  statement.  The  'BREAK'  statement  will
  898.         cause  a branch to the next 'ENDC' statement. The 'BREAK' will
  899.         be  processed  only  if  a  'SWITCH=CASE'  is  true.  When   a
  900.         'SWITCH=CASE'  evaluates  false, processing is branched to the
  901.         next 'CASE' statement. 'SWITCH' statements can  be  nested  to
  902.         ten  (10)  levels.  'ENDC'  closes  the  matching 'SWITCH' and
  903.         terminates to the next outer level of processing.
  904.  
  905.     Usage:
  906.  
  907.            SWITCH method$(method)
  908.            CASE "+"
  909.                answer = answer + number
  910.                BREAK
  911.            CASE "-"
  912.                answer = answer - number
  913.                BREAK
  914.            CASE "*"
  915.                answer = answer * number
  916.                BREAK
  917.            CASE "/"
  918.                when number <> 0
  919.                    answer = answer / number
  920.                else
  921.                    answer = 0
  922.                endw
  923.            ENDC
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937. è
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.    Structure Keyword Definitions and Usage                          Page 1.5
  946.  
  947.  
  948.  
  949.    BSLP Version 1.0B                                                Page 2.1
  950.  
  951.     Structure Related Error Handling:
  952.  
  953.         When   a   structure   error   is    encountered,    a    file
  954.         (<program-name>.E)  is  generated,  showing the exact location
  955.         of the error. All structure errors are resolved at the end  of
  956.         each  procedure,  or 'ENDP'. When there are errors immediately
  957.         following an 'ENDP' statement,  the  procedure  preceding  the
  958.         'ENDP' statement will be the source of the errors.
  959.  
  960.     Structure Related Error Messages:
  961.  
  962.         Structure  related  error messages are displayed with a 'ERR#'
  963.         and the error count. These errors  will  be  recorded  in  the
  964.         error file (<program-name>.E).
  965.  
  966.         Structure  related  error  messages  are self explanatory, the
  967.         following are some typical examples:
  968.  
  969.            ERR#1 MISSING (endl) PROC <BEGIN>
  970.                      (A 'LOOP' structure not closed in procedure BEGIN)
  971.            ERR#1 MISSING (switch) PROC <Select>
  972.                      (A 'CASE' or 'BREAK' or 'ENDC' without an  opening
  973.                       'SWITCH' in procedure Select.)
  974.            ERR#1 MISSING (endc) PROC <>
  975.                      (A 'CASE' structure not closed in main procedure.)
  976.            ERR#1 MISSING (include 'filename')
  977.                      (Unable to find an included file.)
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000. è
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.    Errors                                                           Page 2.1
  1009.  
  1010.  
  1011.  
  1012.    BSLP Version 1.0B                                                Page 3.1
  1013.  
  1014.     Included Files:
  1015.  
  1016.         There are two methods  to  include  additional  files  into  a
  1017.         program source file for processing:
  1018.  
  1019.     Immediate:
  1020.                +filename.ext
  1021.  
  1022.         The  leading  plus  (+)  will  cause  a  file  to  be included
  1023.         immediately into the program source file  and  processed.  The
  1024.         same  file  or  any  number  of  files  may  be  included  and
  1025.         processed.
  1026.  
  1027.     Stacked:
  1028.                -filename.ext
  1029.  
  1030.         The leading dash (-) will cause a file name to be  stored  and
  1031.         the  file  will  be  included  only one time at the end of the
  1032.         main  program  source  file.  The  same  file  name   may   be
  1033.         referenced  many  times,  with  the  file  included  into  the
  1034.         program source file only one time and processed. The  internal
  1035.         file name storage will hold up to fifty (50) file names.
  1036.  
  1037.     *Note:
  1038.  
  1039.         Nested  includes  may be processed up to five (5) levels deep.
  1040.         Nesting is limited by the number of files that can be open  at
  1041.         the same time. No line numbered include files allowed.
  1042.  
  1043.  
  1044.  
  1045.     WARNING:
  1046.  
  1047.         A  recursive include will blow the internal stack. No check is
  1048.         made for recursive includes.
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063. è
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.    Including Files                                                  Page 3.1
  1072.  
  1073.  
  1074. BSLP.P
  1075.  
  1076. '------------------------------------------------------
  1077. '-(c) Bendorf Associates, 1984-85                     -
  1078. '------------------------------------------------------
  1079. '- Program:BSLP (BASIC STRUCTURED LANGUAGE PREPROCESSOR)
  1080. '- System :PPE
  1081. '- Module :TOOLS
  1082. '- Task   :COMPILE 'SSS' CODE INTO STANDARD BASIC CODE.
  1083. '- Created:10.1.82
  1084. '- By     :D. L. BENDORF
  1085. '- Version:PUBLIC DOMAIN
  1086. '- Notes  :THIS PROGRAM IS NOT FOR RESALE.
  1087. '- History:
  1088. '-   BSLP  translates  source  text  written in 'SSS' structure language to
  1089. '-   standard BASIC code. BSLP is a  BASIC  language  version  of  the  PPE
  1090. '-   structure  translater. It is slow but very usable, and has served well
  1091. '-   as a tool for prototype extensions to the structure language. BSLP  is
  1092. '-   written  in  BSLP  structure  language and should be a useful learning
  1093. '-   tool.
  1094. '- Invocation:
  1095. '-   Entering 'BSLP' at the DOS prompt will  envoke  the  compiled  version
  1096. '-   (.EXE)  of  BSLP.  The  (.BAS)  version  will have to be run using the
  1097. '-   interpreter by entering 'BASICA BSLP' at the  DOS  prompt.  BSLP  will
  1098. '-   then  prompt  for  the  input  file name and the output file name. The
  1099. '-   default for the input file extension is '.P', and the default for  the
  1100. '-   output  file  is  'input-file.BAS'.  The slash (/) following the input
  1101. '-   file name will cause all non-referenced line  numbers  to  be  deleted
  1102. '-   from  the  output  file  (.BAS). This allows a smaller compiled (.EXE)
  1103. '-   program.
  1104. '- Hints and Restrictions:
  1105. '-   'SSS'  keywords  are  not  case or position sensitive, and  they  must
  1106. '-   (except  for spaces and tabs) be the first words on a line. Do NOT use
  1107. '-   comments on the same line with keywords. The vertical bar (|)  may  be
  1108. '-   use  to  provide  line continuation. Continued lines will be appended,
  1109. '-   separating them with a colon (:).
  1110. '- 'SSS' Keywords:
  1111. '-   PROG / PEND
  1112. '-   PROC <label> / ENDP
  1113. '-   REPEAT / UNTIL <condition>
  1114. '-   LOOP [<when/unless> <condition>] / ENDL [<when/unless> <condition>]
  1115. '-   WHEN <condition> / ELSE [<when/unless> <condition>] / ENDW
  1116. '-   UNLESS <condition> / ENDU
  1117. '-   SWITCH <left operand> / CASE <right operand> / BREAK / ENDC
  1118. '------------------------------------------------------
  1119. '- ** Data Division                                   -
  1120. '------------------------------------------------------
  1121. DATA   proc...
  1122. DATA   prog...
  1123. DATA   when...
  1124. DATA   unless.
  1125. DATA   repeat.èDATA   loop...
  1126. DATA   switch.
  1127. DATA   case...
  1128. DATA   else...
  1129. DATA   break..
  1130. DATA   endp...
  1131. DATA   pend...
  1132. DATA   endw...
  1133. DATA   endu...
  1134. DATA   until..
  1135. DATA   endl...
  1136. DATA   endc...
  1137. PROC.%   = 1
  1138. PROG.%   = 2
  1139. WHEN.%   = 3
  1140. UNLESS.% = 4
  1141. REPEAT.% = 5
  1142. LOOP.%   = 6
  1143. SWITCH.% = 7
  1144. CASE.%   = 8
  1145. ELSE.%   = 9
  1146. BREAK.%  = 10
  1147. ENDP.%   = 11
  1148. PEND.%   = 12
  1149. ENDW.%   = 13
  1150. ENDU.%   = 14
  1151. UNTIL.%  = 15
  1152. ENDL.%   = 16
  1153. ENDC.%   = 17
  1154. DATA 11,12,13,14,15,16,17,17,13,17
  1155. DOT$     = "."
  1156. DOTS$    = "...."
  1157. SKIP$    = " "
  1158. SKIP1$   = "  '"
  1159. OEXT$    = ".BAS"
  1160. IEXT$    = ".P"
  1161. EEXT$    = ".E"
  1162. INCL$    = ".INC"
  1163. TM$      = " ,="
  1164. T.FILE$  = "BSLP.$$$"
  1165. T.FILE%  = 1
  1166. E.FILE%  = 2
  1167. I.FILE%  = 3
  1168. O.FILE%  = 3
  1169. ERRORS%  = 0
  1170. KERR%    = 1
  1171. LEVELS%  = 0
  1172. PUSH%    = 0
  1173. NUM%     = 0
  1174. STACK.%  = 0
  1175. NKEY%    = 17
  1176. INCS%    = 1
  1177. INC%     = 0
  1178. FILE%    = 2
  1179. BASIC$   = "restore.resume.return.goto.gosub"èDIM CLOSING%(10)        ' For error messages.
  1180. DIM INC$(50)            ' Include file stack.
  1181. DIM STACK$(500)
  1182. DIM STACK%(500)
  1183. DIM NUM.%(500)
  1184. DIM KEYWORD.%(99,2)
  1185. DIM XN.%(99)
  1186. DIM LOOPS%(99)
  1187. DIM SWITCH$(10)         ' For the left operand of SWITCH.
  1188. DIM KEYWORD$(22)        ' For error messages.
  1189. FOR I%=1 TO NKEY%|
  1190.     READ BUF$|
  1191.     TABLE$=TABLE$+BUF$|
  1192.     KEYWORD$(I%)=BUF$|
  1193. NEXT I%
  1194. FOR I%=1 TO 10|
  1195.     READ CLOSING%(I%)|
  1196. NEXT I%
  1197. '------------------------------------------------------
  1198. '- ** Procedure Division                              -
  1199. '------------------------------------------------------
  1200. prog BSLP
  1201.     PRINT "BSLP   V1.1B (C) BENDORF ASSOCIATES, 1984-85"
  1202.     PRINT|
  1203.     GoSub FILENAMES
  1204.     when GOOD%
  1205.         GoSub BEGIN
  1206.     else when I.FILE$<>""
  1207.         PRINT"CANNOT OPEN ";I.FILE$
  1208.     endw
  1209. pend
  1210. proc BEGIN
  1211.     GoSub PASS_1
  1212.     '
  1213.     ' Kill the error file if no errors in PASS_1.
  1214.     ' Kill the temp file after PASS_2.
  1215.     ' Kill the output file if errors in PASS_2.
  1216.     '
  1217.     CLOSE
  1218.     when ERRORS%=0
  1219.         KILL E.FILE$|
  1220.         GoSub PASS_2|
  1221.         CLOSE|
  1222.         KILL T.FILE$
  1223.     else
  1224.         KILL T.FILE$|
  1225.         PRINT E.FILE$;" PRODUCED WITH ";STR$(ERRORS%);" ERROR(S)."
  1226.         END
  1227.     endw
  1228.     when ERRORS%>0
  1229.         KILL O.FILE$|
  1230.         PRINT O.FILE$;" ABORTED WITH ";STR$(ERRORS%);" ERROR(S)."
  1231.     else
  1232.         PRINT"<";O.FILE$;"> DONE!"
  1233.     endwèendp
  1234. proc PASS_1
  1235.     '
  1236.     ' This is the first phase of processing.
  1237.     ' All included file will be processed here.
  1238.     ' The error file is written during this pass.
  1239.     '
  1240.     Open"O",T.FILE%,T.FILE$|
  1241.     Open"O",E.FILE%,E.FILE$|
  1242.     GoSub PUSH|
  1243.     INC$(INCS%)=I.FILE$
  1244.     loop
  1245.         INC%=INC%+1|
  1246.         FILE%=FILE%+1|
  1247.         FILE$=INC$(INC%)|
  1248.         Open"I",FILE%,FILE$
  1249.         loop
  1250.             GoSub INPUT-SOURCE|
  1251.             GoSub POP_ERRORS
  1252.         until FILE%=2
  1253.     until INC%=INCS%
  1254. endp
  1255. proc INPUT-SOURCE
  1256.     '
  1257.     ' Read the input file and look for SLP keywords.
  1258.     ' Look for include file operators(+-).
  1259.     ' Write error file just in case there is a PASS_1 error.
  1260.     '
  1261.     loop
  1262.         LINE INPUT #FILE%,BUF$
  1263.         when LEN(BUF$)>2
  1264.             XLINE$=BUF$:GoSub STRIP
  1265.             unless LEN(BUF$)=0
  1266.                 INDEX%=0:GoSub PARSER
  1267.                 when RIGHT$(TEXT$,1)=":"
  1268.                     IF(LEN(SBUFF$)>0)THEN GoSub DUMP
  1269.                     FLAG%=2:LEVEL$=LEFT$(TEXT$,LEN(TEXT$)-1)|
  1270.                     COMMENT$=SKIP1$+LEVEL$|
  1271.                     GoSub OUT_LINE
  1272.                 else
  1273.                     L$=LEFT$(TEXT$,1):KEYWORD%=0
  1274.                     unless LEN(TEXT$)<4 OR LEN(TEXT$)>6
  1275.                         C.$=TEXT$:GoSub _Fold|
  1276.                         KEYS$=C.$+DOTS$|
  1277.                         KEYWORD%=INSTR(1,TABLE$,LEFT$(KEYS$,7))|
  1278.                         KEYWORD%=(KEYWORD%+6)\7
  1279.                     endu
  1280.                     when KEYWORD%>0
  1281.                         IF(LEN(SBUFF$)>0)THEN GoSub DUMP
  1282.                         GoSub KEYWORDS
  1283.                     else when L$="-"
  1284.                         GoSub SUBROUTINE
  1285.                     else when L$="+"
  1286.                         IF(LEN(SBUFF$)>0)THEN GoSub DUMP
  1287.                         GoSub INCLUDESè                    else 
  1288.                         GoSub OUT_PUT
  1289.                     endw
  1290.                 endw
  1291.             endu
  1292.             NERR%=NERR%+1|
  1293.             PRINT #E.FILE%,STR$(NERR%);SKIP$;XLINE$
  1294.         endw
  1295.     until EOF(FILE%)
  1296.     CLOSE #FILE%|
  1297.     FILE%=FILE%-1
  1298.     unless SBUFF$=""
  1299.         BUF$="":CFLAG%=0:GoSub OUT_PUT
  1300.     endu
  1301. endp
  1302. proc STRIP
  1303.     '
  1304.     ' Strip the leading and trailing spaces,tabs and linefeeds off of
  1305.     ' the input buffer.
  1306.     ' Look for the continuation operator.
  1307.     '
  1308.     Z1%=INSTR(BUF$,CHR$(9)):Z2%=INSTR(BUF$,CHR$(10))
  1309.     WHILE (Z1% OR Z2%)
  1310.         IF Z1% THEN MID$(BUF$,Z1%,1)=" "
  1311.         IF Z2% THEN MID$(BUF$,Z2%,1)=" "
  1312.         Z1%=INSTR(BUF$,CHR$(9)):Z2%=INSTR(BUF$,CHR$(10))|
  1313.     WEND
  1314.     Z1%=1|
  1315.     WHILE (MID$(BUF$,Z1%,1)=" " AND Z1%<LEN(BUF$))|
  1316.         Z1%=Z1%+1|
  1317.     WEND
  1318.     Z2%=LEN(BUF$)|
  1319.     WHILE (MID$(BUF$,Z2%,1)=" " AND Z2%>1)|
  1320.         Z2%=Z2%-1|
  1321.     WEND
  1322.     when Z2%<Z1%
  1323.         BUF$=""
  1324.     else
  1325.         BUF$=MID$(BUF$,Z1%,Z2%-Z1%+1)
  1326.         when LEN(BUF$)>0
  1327.             IF(LEFT$(BUF$,1)="'" OR LEFT$(BUF$,3)="REM" OR BUF$=STRING$(LEN(BUF$),32))THEN BUF$=""
  1328.         endw
  1329.     endw
  1330.     LN.%=LEN(BUF$):CFLAG%=0
  1331.     unless LN.%=0
  1332.         CFLAG%=(RIGHT$(BUF$,1)="|")
  1333.         IF(CFLAG%)THEN BUF$=LEFT$(BUF$,LN.%-1):LN.%=LEN(BUF$)
  1334.     endu
  1335. endp
  1336. proc OUT_PUT
  1337.     '
  1338.     ' Process lines not beginning with keywords.
  1339.     ' If CFLAG% flag is set, append input lines together
  1340.     ' and always check the total length first.
  1341.     'è    when CFLAG%=0 
  1342.         when LEN(SBUFF$)>0
  1343.             when LEN(SBUFF$+BUF$)<=250
  1344.                 BUF$=SBUFF$+BUF$:SBUFF$=""
  1345.             else
  1346.                 GoSub DUMP
  1347.             endw
  1348.         endw
  1349.         PBUF$=BUF$:FLAG%=3:GoSub OUT_LINE
  1350.     else when LEN(SBUFF$+BUF$)<=250
  1351.         SBUFF$=SBUFF$+BUF$+":"
  1352.     else
  1353.         GoSub DUMP:PBUF$=BUF$:GoSub OUT_LINE
  1354.     endw
  1355.     BUF$=""
  1356. endp
  1357. proc DUMP
  1358.     PBUF$=LEFT$(SBUFF$,LEN(SBUFF$)-1)|
  1359.     FLAG%=3:GoSub OUT_LINE:SBUFF$="":CFLAG%=0
  1360. endp
  1361. proc KEYWORDS
  1362.     '
  1363.     ' Branch to the right keyword processing.
  1364.     ' This is one of the few acceptable uses of the `GOTO'.
  1365.     '
  1366.     KERR%=NERR%+1
  1367.     ON KEYWORD% GOTO _PROC,_PROG,_WHEN,_UNLESS,_REPEAT,_REPEAT
  1368.     ON KEYWORD%-6 GOTO _SWITCH,_CASE,_ELSE,_BREAK,_ENDP,_PEND,_ENDW
  1369.     ON KEYWORD%-13 GOTO _ENDU,_UNTIL,_ENDL,_ENDC
  1370. endp
  1371. proc POP_ERRORS
  1372.     '
  1373.     ' Resolve all un-closed processes and report errors.
  1374.     '
  1375.     KER%=KERR%:KWDS%=KEYWORD%:GoSub POP
  1376.     while KEYWORD%>0
  1377.         GoSub RESOLVE-ERRORS
  1378.     wend
  1379.     GoSub PUSH:KEYWORD%=KWDS%:KERR%=KER%
  1380. endp
  1381. proc RESOLVE-ERRORS
  1382.     IF(KEYWORD%<11)THEN KEYWORD%=CLOSING%(KEYWORD%)
  1383.     EBUF$=KEYWORD$(KEYWORD%):GoSub ERRORS
  1384.     when KEYWORD%=ENDW.% OR KEYWORD%=ENDU.% OR KEYWORD%=ENDC.%
  1385.         IF(KEYWORD%=ENDC.%)THEN GoSub POP
  1386.         GoSub POP
  1387.     endw
  1388.     GoSub POP
  1389. endp
  1390. proc PUSH
  1391.     PUSH%=PUSH%+1|
  1392.     KEYWORD.%(PUSH%,0)=KEYWORD%|
  1393.     KEYWORD.%(PUSH%,1)=KERR%|
  1394.     KEYWORD.%(PUSH%,2)=LEVEL%
  1395. endpèproc POP
  1396.     when PUSH%>0
  1397.         KEYWORD%=KEYWORD.%(PUSH%,0)|
  1398.         KERR%=KEYWORD.%(PUSH%,1)|
  1399.         LEVEL%=KEYWORD.%(PUSH%,2)|        
  1400.         PUSH%=PUSH%-1
  1401.     else
  1402.         LEVEL%=-1|
  1403.         KEYWORD%=-1
  1404.     endw
  1405. endp
  1406. proc LEVEL
  1407.     LEVELS%=LEVELS%+1:LEVEL%=LEVELS%|
  1408.     TK%=LEVEL%:GoSub PUSH
  1409. endp
  1410. proc _PROC
  1411.     GoSub POP_ERRORS|
  1412.     GoSub PUSH|
  1413.     GoSub PARSER
  1414.     when LEN(TEXT$)>0
  1415.         COMMENT$=SKIP1$+TEXT$:LPROC$=TEXT$|
  1416.         FLAG%=2:LEVEL$=TEXT$:GoSub OUT_LINE
  1417.     else
  1418.         EBUF$="procedure name":GoSub ERRORS
  1419.     endw
  1420. endp
  1421. proc _ENDP
  1422.     GoSub POP
  1423.     WHILE KEYWORD%<>PROC.% AND KEYWORD%>0
  1424.         GoSub RESOLVE-ERRORS
  1425.     WEND        
  1426.     when KEYWORD%=PROC.%
  1427.         FLAG%=3:PBUF$="RETURN":GoSub OUT_LINE
  1428.     else
  1429.         EBUF$=KEYWORD$(PROC.%):GoSub ERRORS
  1430.     endw
  1431. endp
  1432. proc _PROG
  1433.     PROG..%=1
  1434. endp
  1435. proc _PEND
  1436.     when PROG..%=1
  1437.         FLAG%=3:PBUF$="END":GoSub OUT_LINE
  1438.     else
  1439.         EBUF$=KEYWORD$(PROG.%):GoSub ERRORS
  1440.     endw
  1441. endp
  1442. proc _WHEN
  1443.     GoSub LEVEL:GoSub LEVEL|
  1444.     FLAG%=1:GoSub OUT_LINE
  1445. endp
  1446. proc _ELSE
  1447.     GoSub POP
  1448.     when KEYWORD%=WHEN.%
  1449.         F.%=LEVEL%:GoSub POP:T.%=LEVEL%:TK%=T.%|è        FLAG%=4:PBUF$="GOTO ":GoSub OUT_LINE|
  1450.         XN%=XN%+1:XN.%(XN%)=F.%|
  1451.         GoSub PARSER:C.$=TEXT$:GoSub _Fold
  1452.         when C.$="when" OR C.$="unless"
  1453.             GoSub LEVEL:F.%=LEVEL%|
  1454.             FLAG%=ABS(C.$="when"):GoSub OUT_LINE:GoSub POP
  1455.         else
  1456.             F.%=0
  1457.         endw
  1458.         KEYWORD%=WHEN.%|
  1459.         LEVEL%=T.%:GoSub PUSH|
  1460.         LEVEL%=F.%:GoSub PUSH
  1461.     else
  1462.         GoSub PUSH|
  1463.         EBUF$=KEYWORD$(WHEN.%):GoSub ERRORS
  1464.     endw
  1465. endp
  1466. proc _ENDW
  1467.     GoSub POP
  1468.     when KEYWORD%=WHEN.%
  1469.         F.%=LEVEL%:GoSub POP:T.%=LEVEL%:GoSub POPOFF
  1470.     else
  1471.         GoSub PUSH|
  1472.         EBUF$=KEYWORD$(WHEN.%):GoSub ERRORS
  1473.     endw
  1474. endp
  1475. proc POPOFF
  1476.     IF(F.%>0)THEN XN%=XN%+1:XN.%(XN%)=F.%
  1477.     IF(T.%>0)THEN XN%=XN%+1:XN.%(XN%)=T.%
  1478. endp
  1479. proc _UNLESS
  1480.     GoSub LEVEL:GoSub LEVEL|
  1481.     FLAG%=0:GoSub OUT_LINE
  1482. endp
  1483. proc _ENDU
  1484.     GoSub POP
  1485.     when KEYWORD%=UNLESS.%
  1486.         F.%=LEVEL%:GoSub POP:T.%=LEVEL%:GoSub POPOFF
  1487.     else
  1488.         GoSub PUSH|
  1489.         EBUF$=KEYWORD$(UNLESS.%):GoSub ERRORS
  1490.     endw
  1491. endp
  1492. proc _REPEAT
  1493.     GoSub PARSER:C.$=TEXT$:GoSub _Fold|
  1494.     LOOP%=LOOP%+1:GoSub LEVEL|
  1495.     XN%=XN%+1:XN.%(XN%)=LEVEL%
  1496.     when C.$<>"when" AND C.$<>"unless"
  1497.         LOOPS%(LOOP%)=LEVEL%|
  1498.     else
  1499.         LOOPS%(LOOP%)=LEVEL%*-1|
  1500.         GoSub POP:LEVEL%=LEVEL%*-1:GoSub PUSH|
  1501.         GoSub LEVEL|
  1502.         FLAG%=ABS(C.$="when")|
  1503.         GoSub OUT_LINEè    endw
  1504. endp
  1505. proc _UNTIL
  1506.     when LOOP%>0
  1507.         GoSub POP
  1508.         when KEYWORD%=REPEAT.% OR KEYWORD%=LOOP.%
  1509.             LOOP%=LOOP%-1:TK%=LOOPS%(LOOP%+1)|
  1510.             FLAG%=1:GoSub OUT_LINE
  1511.         else
  1512.             GoSub PUSH|
  1513.             EBUF$=KEYWORD$(REPEAT.%):GoSub ERRORS
  1514.         endw
  1515.     else
  1516.         EBUF$=KEYWORD$(REPEAT.%):GoSub ERRORS
  1517.     endw
  1518. endp
  1519. proc _ENDL
  1520.     when LOOP%>0
  1521.         GoSub POP
  1522.         when KEYWORD%=REPEAT.% OR KEYWORD%=LOOP.%
  1523.             GoSub PARSER:C.$=TEXT$:GoSub _Fold|
  1524.             LOOP%=LOOP%-1
  1525.             when LOOPS%(LOOP%+1)>0
  1526.                 TK%=LOOPS%(LOOP%+1)
  1527.                 when C.$="when" OR C.$="unless"
  1528.                     FLAG%=ABS(C.$="when"):GoSub OUT_LINE
  1529.                 else
  1530.                     EBUF$=KEYWORD$(WHEN.%):GoSub ERRORS
  1531.                 endw
  1532.             else
  1533.                 TK%=LOOPS%(LOOP%+1)*-1
  1534.                 when C.$="when" OR C.$="unless"
  1535.                     FLAG%=ABS(C.$="when")
  1536.                 else
  1537.                     FLAG%=4:PBUF$="GOTO "
  1538.                 endw
  1539.                 GoSub OUT_LINE
  1540.                 F.%=LEVEL%:GoSub POP:T.%=LEVEL%:GoSub POPOFF
  1541.             endw
  1542.         else
  1543.             GoSub PUSH|
  1544.             EBUF$=KEYWORD$(LOOP.%):GoSub ERRORS
  1545.         endw
  1546.     else
  1547.         EBUF$=KEYWORD$(LOOP.%):GoSub ERRORS
  1548.     endw
  1549. endp
  1550. proc _SWITCH
  1551.     when C.LN.%>0
  1552.         GoSub LEVEL:GoSub LEVEL:GoSub LEVEL|
  1553.         SWITCH$(SWITCH%+1)=COND$|
  1554.         SWITCH%=SWITCH%+1
  1555.     else
  1556.         EBUF$="operand":GoSub ERRORS
  1557.     endwèendp
  1558. proc _CASE
  1559.     GoSub POP
  1560.     when KEYWORD%=SWITCH.% AND SWITCH%>0
  1561.         when C.LN.%>0
  1562.             XN%=XN%+1:XN.%(XN%)=LEVEL%|
  1563.             GoSub LEVEL:FLAG%=4|
  1564.             PBUF$="IF("+SWITCH$(SWITCH%)+"<>"+COND$+") GOTO "|
  1565.             GoSub OUT_LINE
  1566.         else
  1567.             EBUF$="operand":GoSub ERRORS
  1568.         endw
  1569.     else
  1570.         GoSub PUSH|
  1571.         EBUF$=KEYWORD$(SWITCH.%):GoSub ERRORS
  1572.     endw
  1573. endp
  1574. proc _BREAK
  1575.     GoSub POP
  1576.     when KEYWORD%=SWITCH.%
  1577.         F.%=LEVEL%:GoSub POP:T.%=LEVEL%:TK%=T.%|
  1578.         FLAG%=4:PBUF$="GOTO ":GoSub OUT_LINE|
  1579.         KEYWORD%=SWITCH.%|
  1580.         LEVEL%=T.%:GoSub PUSH|
  1581.         LEVEL%=F.%:GoSub PUSH
  1582.     else
  1583.         GoSub PUSH|
  1584.         EBUF$=KEYWORD$(SWITCH.%):GoSub ERRORS
  1585.     endw
  1586. endp
  1587. proc _ENDC
  1588.     GoSub POP
  1589.     when KEYWORD%=SWITCH.%
  1590.         F.%=LEVEL%:GoSub POP:T.%=LEVEL%:GoSub POP|
  1591.         GoSub POPOFF:SWITCH%=SWITCH%-1
  1592.     else
  1593.         GoSub PUSH|
  1594.         EBUF$=KEYWORD$(SWITCH.%):GoSub ERRORS
  1595.     endw
  1596. endp
  1597. proc OUT_LINE
  1598.     '
  1599.     ' Build and output lines to the temp file.
  1600.     '
  1601.     when FLAG%<2 AND C.LN.%=0
  1602.         EBUF$="condition":GoSub ERRORS
  1603.     else
  1604.         NUM%=NUM%+1:OFFSET%=1
  1605.         IF(FLAG%<2 OR FLAG%>3)THEN LEVEL$=STR$(TK%):MID$(LEVEL$,1,1)="@"
  1606.         switch FLAG%
  1607.         case 0
  1608.             PBUF$="IF("+COND$+") GOTO "+LEVEL$
  1609.         break
  1610.         case 1
  1611.             PBUF$="IF NOT("+COND$+") GOTO "+LEVEL$è        break
  1612.         case 2
  1613.             GoSub STACK_IT
  1614.         break
  1615.         case 4
  1616.             PBUF$=PBUF$+LEVEL$
  1617.         endc
  1618.         PRINT #T.FILE%,RIGHT$(STR$(NUM%),LEN(STR$(NUM%))-1);SKIP$;PBUF$;COMMENT$
  1619.         IF(XN%>0 AND FLAG%<>2)THEN GoSub STORE_IT
  1620.     endw
  1621.     COMMENT$="":PBUF$="":LEVEL$=""
  1622. endp
  1623. proc STORE_IT
  1624.     '
  1625.     ' Pop off the target place savers and make tokens of them.
  1626.     '
  1627.     OFFSET%=0|
  1628.     FOR I%=1 TO XN%|
  1629.         LEVEL$=STR$(XN.%(I%)):MID$(LEVEL$,1,1)="@"|
  1630.         GoSub STACK_IT|
  1631.     NEXT I%|
  1632.     XN%=0
  1633. endp
  1634. proc STACK_IT
  1635.     '
  1636.     ' Store the tokens and labels with their corresponding line numbers.
  1637.     '
  1638.     STACK.%=STACK.%+1|
  1639.     STACK%(STACK.%)=NUM%+OFFSET%|
  1640.     STACK$(STACK.%)=LEVEL$|
  1641.     IF(COMPIL%)THEN NUM.%(STACK.%)=NUM%+OFFSET%
  1642.     OFFSET%=0
  1643. endp
  1644. proc PASS_2
  1645.     '
  1646.     ' This is the second phase of processing.
  1647.     ' First the stack has to be sorted in ascending order,
  1648.     ' so we can use a binary search on it.
  1649.     ' Then we read the temp file and process it a line at
  1650.     ' a time.
  1651.     '
  1652.     GoSub SORT|
  1653.     OFFSET%=2|
  1654.     Open"I",T.FILE%,T.FILE$|
  1655.     Open"O",O.FILE%,O.FILE$
  1656.     loop
  1657.         LINE INPUT #T.FILE%,BUF$|
  1658.         GoSub PROCESS_1
  1659.     until EOF(T.FILE%)
  1660. endp
  1661. proc PROCESS_1
  1662.     '
  1663.     ' Scan the input line a word at a time.
  1664.     ' The first word will be the line number.
  1665.     ' Then write the line to the output file.è    '
  1666.     INDEX%=0:ONFLAG%=0:LN.%=LEN(BUF$)|
  1667.     GoSub PARSER|
  1668.     IF(COMPIL%)THEN GoSub COMPIL
  1669.     while FIRST%<=LEN(BUF$)
  1670.         unless LEN(TEXT$)>7 OR LEN(TEXT$)<2 OR VAL(TEXT$)>0
  1671.             GoSub FIND_IT
  1672.         endu
  1673.         GoSub PARSER
  1674.     wend
  1675.     PRINT #O.FILE%,BUF$
  1676. endp
  1677. proc COMPIL
  1678.     '
  1679.     ' Binary search the number stack to see if the line number is used.
  1680.     '
  1681.     TEXT%=VAL(TEXT$):HIGH%=STACK.%+1:LOW%=0
  1682.     unless TEXT%<NUM.%(1) OR TEXT%>NUM.%(STACK.%)
  1683.         while((HIGH%-LOW%)>1)|
  1684.             I%=(HIGH%+LOW%)\2
  1685.             when NUM.%(I%)=TEXT%
  1686.                 TEXT%=-1:LOW%=HIGH%
  1687.             else when NUM.%(I%)<TEXT%
  1688.                 LOW%=I%
  1689.             else
  1690.                 HIGH%=I%
  1691.             endw
  1692.         wend
  1693.     endu
  1694.     IF(TEXT%>0)THEN BUF$=SPACE$(LEN(TEXT$)+1)+COND$
  1695. endp
  1696. proc FIND_IT
  1697.     '
  1698.     ' Look for BASIC'S keywords and get the token/label to replace
  1699.     ' with the corresponding line number.
  1700.     '
  1701.     C.$=TEXT$:GoSub _Fold
  1702.     when C.$="on"
  1703.         ONFLAG%=-1
  1704.     else when LEN(C.$)>3
  1705.         unless INSTR(BASIC$,C.$)=0 OR COLN%
  1706.             GoSub PARSER:I$=LEFT$(TEXT$,1)
  1707.             unless I$="@" OR LEN(TEXT$)<>4
  1708.                 C.$=TEXT$:GoSub _Fold|
  1709.                 IF(C.$="else")THEN RETURN
  1710.             endu
  1711.             unless I$="0" AND ONFLAG%
  1712.                 IF(ONFLAG%)THEN GoSub ON_FLAG ELSE GoSub SEARCH
  1713.             endu
  1714.         endu
  1715.     endw
  1716. endp
  1717. proc ON_FLAG
  1718.     '
  1719.     ' Resolve the `ON GOTO' or `ON GoSub' statements. è    ' Parse all the way to the end of the input line.
  1720.     '
  1721.     OFFSET%=1
  1722.     while(FIRST%<=LEN(BUF$))
  1723.         IF(TEXT$<>"")THEN GoSub SEARCH
  1724.         GoSub PARSER
  1725.     wend
  1726.     OFFSET%=2    
  1727. endp
  1728. proc SEARCH
  1729.     '
  1730.     ' Binary search the token stack to get the corresponding line number.
  1731.     '
  1732.     HIGH%=STACK.%+1:LOW%=0:FIND%=-1
  1733.     while((HIGH%-LOW%)>1)|
  1734.         I%=(HIGH%+LOW%)\2
  1735.         when STACK$(I%)=TEXT$
  1736.             FIND%=STACK%(I%):LOW%=HIGH%
  1737.         else when STACK$(I%)<TEXT$
  1738.             LOW%=I%
  1739.         else
  1740.             HIGH%=I%
  1741.         endw
  1742.     wend
  1743.     when FIND%>0
  1744.         GoSub STUFF_IT
  1745.     else when TEXT$<>""
  1746.         ERRORS%=ERRORS%+1|
  1747.         PRINT"MISSING LABEL (";TEXT$;")"
  1748.     endw
  1749. endp
  1750. proc STUFF_IT
  1751.     '
  1752.     ' Replace the token/label with the corresponding line number.
  1753.     '
  1754.     NUM$=STR$(FIND%):SP$=""|
  1755.     L$=LEFT$(BUF$,FIRST%-OFFSET%)
  1756.     IF(LEFT$(COND$,1)<>" " AND LEFT$(COND$,1)<>":" AND ONFLAG%=0)THEN SP$=" "
  1757.     BUF$=L$+NUM$+SP$+COND$|
  1758.     INDEX%=LEN(L$)+LEN(NUM$)|
  1759.     LN.%=LEN(BUF$)
  1760. endp
  1761. proc SORT
  1762.     '
  1763.     ' Shell-Metzner in-memory sort of the token/label stack.
  1764.     ' Sort the line number stack if the compile flag is set.
  1765.     '
  1766.     PT.%=STACK.%|
  1767.     while (PT.%>0)|
  1768.         PT.%=PT.%\2
  1769.         when PT.%>0
  1770.             JT.%=1:KT.%=STACK.%-PT.%|
  1771.             while (JT.%<=KT.%)|
  1772.                 LT.%=JT.%:CT.%=LT.%+PT.%
  1773.                 while (LT.%>0 AND STACK$(LT.%)>=STACK$(CT.%))è                    SWAP STACK$(LT.%),STACK$(CT.%)|
  1774.                     SWAP STACK%(LT.%),STACK%(CT.%)
  1775.                     CT.%=LT.%:LT.%=LT.%-PT.%:LT.%=LT.%*(1+(LT.%<0))
  1776.                 wend
  1777.                 when COMPIL%
  1778.                     LT.%=JT.%:CT.%=LT.%+PT.%
  1779.                     while (LT.%>0 AND NUM.%(LT.%)>=NUM.%(CT.%))
  1780.                         SWAP NUM.%(LT.%),NUM.%(CT.%)|
  1781.                         CT.%=LT.%:LT.%=LT.%-PT.%:LT.%=LT.%*(1+(LT.%<0))
  1782.                     wend
  1783.                 endw                        
  1784.                 JT.%=JT.%+1|
  1785.             wend
  1786.         endw
  1787.     wend
  1788. endp
  1789. '------------------------------------------------------
  1790. '- ** Sub-Routine Division                            -
  1791. '------------------------------------------------------
  1792. proc PARSER
  1793.     C.LN.%=0:I.%=0:COLN%=0:II%=32:TEXT%=0:COND$=""|
  1794.     TRM$=TM$+CHR$(58*ABS(INDEX%>0))
  1795.     while(INSTR(TRM$,CHR$(II%))>0)|
  1796.         INDEX%=INDEX%+1|
  1797.         IF(INDEX%<=LEN(BUF$))THEN II%=ASC(MID$(BUF$,INDEX%,1)) ELSE II%=7
  1798.     wend|
  1799.     FIRST%=INDEX%
  1800.     while(II%<>32 AND II%<>7)
  1801.         when INSTR(TRM$,CHR$(II%))>0 AND TEXT%=0
  1802.             COLN%=(CHR$(II%)=":"):I.%=1:II%=32
  1803.         else 
  1804.             when II%=34 OR II%=40 OR II%=41
  1805.                 IF(II%=34)THEN INDEX%=INSTR(INDEX%+1,BUF$,CHR$(34))
  1806.                 IF(II%=40)THEN TEXT%=TEXT%+1 ELSE IF(II%=41)THEN TEXT%=TEXT%-1
  1807.             endw
  1808.             loop 
  1809.                 INDEX%=INDEX%+1|
  1810.                 IF(INDEX%<=LEN(BUF$))THEN II%=ASC(MID$(BUF$,INDEX%,1)) ELSE II%=7
  1811.             endl unless II%=32 AND TEXT%<>0
  1812.         endw
  1813.     wend
  1814.     TEXT$=MID$(BUF$,FIRST%,INDEX%-FIRST%)|
  1815.     IF(LEN(BUF$)>INDEX%)THEN COND$=RIGHT$(BUF$,(LEN(BUF$)-INDEX%)+I.%):C.LN.%=LEN(COND$)
  1816. endp
  1817. proc FILENAMES
  1818.     LINE INPUT"INPUT FILE [.P]:",I.FILE$
  1819.     unless I.FILE$=""
  1820.         COMPIL%=(INSTR(I.FILE$,"/")>0)
  1821.         IF(COMPIL%)THEN I.FILE$=LEFT$(I.FILE$,LEN(I.FILE$)-1)
  1822.         IF(INSTR(I.FILE$,DOT$)=0)THEN I.FILE$=I.FILE$+IEXT$
  1823.         LK.$=I.FILE$:LK.%=I.FILE%:GoSub _Lookup:I.FILE%=LK.%|
  1824.         GOOD%=(I.FILE%<>FALSE%)
  1825.         unless GOOD%=FALSE%
  1826.             I%=INSTR(1,I.FILE$,DOT$)
  1827.             IF(I%=0)THEN I%=LEN(I.FILE$)+1è            E.FILE$=LEFT$(I.FILE$,I%-1)|
  1828.             LINE INPUT"OUTPUT FILE [.BAS]:",O.FILE$
  1829.             IF(O.FILE$="")THEN O.FILE$=E.FILE$
  1830.             IF(INSTR(O.FILE$,DOT$)=0)THEN O.FILE$=O.FILE$+OEXT$
  1831.             E.FILE$=E.FILE$+EEXT$
  1832.         endu
  1833.     endu
  1834. endp
  1835. proc INCLUDES
  1836.     GoSub FILES
  1837.     when FILE.%>0
  1838.         Open"I",FILE.%,FILE$|
  1839.         FILE%=FILE.%
  1840.     else
  1841.         EBUF$="include "+FILE$:GoSub ERRORS
  1842.     endw
  1843. endp
  1844. proc SUBROUTINE
  1845.     GoSub FILES
  1846.     when FILE.%>0
  1847.         TEXT%=0
  1848.         while(TEXT%<INCS%)
  1849.             TEXT%=TEXT%+1|
  1850.             IF(FILE$=INC$(TEXT%))THEN TEXT%=INCS%+1
  1851.         wend
  1852.         IF(TEXT%=INCS%)THEN INCS%=INCS%+1:INC$(INCS%)=FILE$
  1853.     else
  1854.         EBUF$="include "+FILE$:GoSub ERRORS
  1855.     endw
  1856. endp
  1857. proc FILES
  1858.     FILE$=RIGHT$(TEXT$,LEN(TEXT$)-1)|
  1859.     IF(INSTR(FILE$,DOT$)=0)THEN FILE$=FILE$+INCL$
  1860.     FILE.%=FILE%+1|
  1861.     LK.$=FILE$:LK.%=FILE.%:GoSub _Lookup:FILE.%=LK.%
  1862. endp
  1863. proc ERRORS
  1864.     ERRORS%=ERRORS%+1|
  1865.     EBUF$="ERR#"+STR$(ERRORS%)+" MISSING ("+EBUF$+") PROC <"+LPROC$+">"|
  1866.     EBUF$=EBUF$+" AT"+STR$(KERR%)|
  1867.     PRINT EBUF$:PRINT #E.FILE%,EBUF$
  1868. endp
  1869. proc _Fold
  1870.     f.0%=1
  1871.     while(f.0%<=LEN(C.$))
  1872.         f.2%=ASC(MID$(C.$,f.0%,1))
  1873.         f.2%=f.2%+(32*ABS(f.2%>64 AND f.2%<91))
  1874.         MID$(C.$,f.0%,1)=CHR$(f.2%):f.0%=f.0%+1
  1875.     wend
  1876. endp
  1877. proc _Lookup
  1878.     OPEN"R",LK.%,LK.$:L.K!=LOF(LK.%):CLOSE LK.%
  1879.     IF(L.K!<1)THEN LK.%=0:KILL LK.$
  1880. endp
  1881. è
  1882. XFRAME.M
  1883.  
  1884. '┌────────────────────────────────────────────────────┐
  1885. '│    UTL: IBM & MSDOS ONLY                           │ 
  1886. '└────────────────────────────────────────────────────┘
  1887. '- Program:XFRAME 
  1888. '- System :PPE TOOLS
  1889. '- Module :UTL
  1890. '- Task   :INSERT FRAMES IN TEXT FILES
  1891. '-        :EXAMPLE SOURCE TO BE PREPROCESSED BY BMLP & BSLP
  1892. '- Created:10.1.84
  1893. '- By     :D. L. Bendorf
  1894. '- Version:N/A
  1895. '- Notes  :This is a simple little program utility to insert pretty 
  1896. '-        :block graphic frames (like those above and below) in text files. 
  1897. '-        :Four types of frames are provided.
  1898. '-        :To insert a frame, you will have to mark the location.
  1899. '-        :This is done by using a `^' carrot for the upper left and right
  1900. '-        :corners and then bottom left corner.
  1901. '-        :Insert a number (0..3) on the right side of the upper left corner
  1902. '-        :to select the type of frame you want; the default is zero.
  1903. '-        :Examples:
  1904. '-        :   1.     ^0    ^            ╔═════╗     
  1905. '-        :                   will make ║     ║ 
  1906. '-        :          ^                  ╚═════╝ 
  1907. '-        :
  1908. '-        :   2.     ^1    ^            ┌─────┐     
  1909. '-        :                   will make │     │ 
  1910. '-        :          ^                  └─────┘ 
  1911. '-        :
  1912. '-        :   3.     ^2    ^            ╓─────╖     
  1913. '-        :                   will make ║     ║ 
  1914. '-        :          ^                  ╙─────╜ 
  1915. '-        :
  1916. '-        :   4.     ^3    ^            ╒═════╕     
  1917. '-        :                   will make │     │ 
  1918. '-        :          ^                  ╘═════╛ 
  1919. '-        :If you need to change then corner-stone (^) to something else,
  1920. '-        :use:  ^=some-other-mark ,example: ^=@
  1921. '-        :Tabs are set to expand to four spaces, to set to some other value,
  1922. '-        :use:  ^Tsome-value , example: ^T8 sets tabs to expand eight spaces. 
  1923. '-         
  1924. '- History:
  1925. '┌────────────────────────────────────────────────────┐
  1926. '│ ** Data Division                                   │
  1927. '└────────────────────────────────────────────────────┘
  1928.  
  1929. LIBRARY XFRAME
  1930.  
  1931. NULL$  = ""
  1932. DOT$   = "."
  1933. BLANK$ = "   "
  1934. I.FILE%=1
  1935. O.FILE%=2èI.FILE$=""
  1936. O.FILE$=""
  1937. XLINE.$=" "
  1938. FALSE% =0
  1939. GOOD%  =0
  1940. MK$    =CHR$(94)
  1941. TB%    =4
  1942. EQUATE$="="
  1943. TABS$  ="T"
  1944. IEXT$  =".DOC"
  1945. OEXT$  =".F"
  1946. macro INSERT
  1947.     BK%=[1]:CK%=[2]:GoSub INSERT-BLOCK
  1948. endm
  1949. macro FSPEC
  1950.     I%=INSTR(1,[1],DOT$):IF(I%=0)THEN [1]=[1]+[2]
  1951. endm
  1952. DIM TLC%(3),TRC%(3),HL%(3),BLC%(3),BRC%(3),VL%(3)
  1953. DIM EL%(20)
  1954. DIM BL%(20)
  1955. DIM MK%(132,20)
  1956. READ TLC%(0),TLC%(1),TLC%(2),TLC%(3)
  1957. READ TRC%(0),TRC%(1),TRC%(2),TRC%(3)
  1958. READ HL%(0),HL%(1),HL%(2),HL%(3)
  1959. READ BLC%(0),BLC%(1),BLC%(2),BLC%(3)
  1960. READ BRC%(0),BRC%(1),BRC%(2),BRC%(3)
  1961. READ VL%(0),VL%(1),VL%(2),VL%(3)
  1962. DATA 201,218,214,213
  1963. DATA 187,191,183,184
  1964. DATA 205,196,196,205
  1965. DATA 200,192,211,212
  1966. DATA 188,217,189,190
  1967. DATA 186,179,186,179
  1968. for I%=0 to 20
  1969.  for Q%=0 to 132
  1970.   MK%(Q%,I%)=-1
  1971.  next Q%
  1972. next I%
  1973. '┌────────────────────────────────────────────────────┐
  1974. '│ ** Procedure Division                              │
  1975. '└────────────────────────────────────────────────────┘
  1976. prog XFRAME
  1977.     GoSub FILENAMES
  1978.  
  1979.     when GOOD%
  1980.         GoSub PROCESS-FILE
  1981.  
  1982.         PRINT"Done!"
  1983.  
  1984.     else unless I.FILE$=NULL$
  1985.  
  1986.         PRINT"Can not open ";I.FILE$
  1987.  
  1988.     endw
  1989. pendèproc FILENAMES
  1990.     line input"INPUT FILE:",I.FILE$
  1991.  
  1992.     unless I.FILE$=NULL$
  1993.  
  1994.         $fspec I.FILE$,IEXT$
  1995.         $lookup I.FILE$,I.FILE%
  1996.         GOOD%=(I.FILE% <> FALSE%)
  1997.  
  1998.         unless GOOD%=FALSE%
  1999.  
  2000.             line input"OUTPUT FILE:",O.FILE$
  2001.  
  2002.             unless O.FILE$<>NULL$
  2003.                 I%=INSTR(1,I.FILE$,DOT$)
  2004.                 IF(I%=0)THEN I%=LEN(I.FILE$)+1
  2005.                 O.FILE$=LEFT$(I.FILE$,I%-1)
  2006.             endu
  2007.  
  2008.             $fspec O.FILE$,OEXT$
  2009.             OPEN"O",O.FILE%,O.FILE$
  2010.             OPEN"I",I.FILE%,I.FILE$
  2011.             PRINT"Writing..";O.FILE$
  2012.  
  2013.         endu
  2014.  
  2015.     endu
  2016. endp
  2017. proc PROCESS-FILE
  2018.     loop
  2019.         $linput I.FILE%,XLINE.$
  2020.         when INSTR(1,XLINE.$,MK$)>0
  2021.             GoSub PROCESS-XLINE
  2022.         else when BQ%>0
  2023.             GoSub INSERT-SIDES
  2024.         endw
  2025.         unless XLINE.$=BLANK$
  2026.             PRINT #O.FILE%,XLINE.$
  2027.         endu
  2028.     until EOF(I.FILE%)
  2029.     CLOSE
  2030. endp
  2031. proc PROCESS-XLINE
  2032.     GoSub REMOVE-TABS
  2033.     DQ%=BQ%
  2034.     I%=0
  2035.     while INSTR(I%+1,XLINE.$,MK$)>0
  2036.         GoSub SCAN-XLINE
  2037.         when IZ%=0
  2038.             IF(DQ%>0)THEN GoSub INSERT-SIDES
  2039.             GoSub TOP-FRAME
  2040.         else
  2041.             GoSub BOTTOM-FRAME    
  2042.         endw
  2043.     wendè    IF(BQ%>0)THEN GoSub INSERT-SIDES
  2044. endp
  2045. proc SCAN-XLINE
  2046.     I%=INSTR(I%+1,XLINE.$,MK$):IK%=0:IZ%=0
  2047.     while IK%<DQ% and IZ%=0
  2048.         IF(MK%(I%,IK%)>-1)THEN IZ%=1 ELSE IK%=IK%+1
  2049.     wend
  2050. endp
  2051. proc TOP-FRAME
  2052.     BL%(BQ%)=I%
  2053.     EL%(BQ%)=INSTR(I%+1,XLINE.$,MK$)
  2054.     when EL%(BQ%)>0
  2055.         FT%=VAL(MID$(XLINE.$,I%+1,1))
  2056.         MID$(XLINE.$,I%+1,1)=" "
  2057.         IF(EL%(BQ%)>EK%)THEN EK%=EL%(BQ%)
  2058.         MK%(BL%(BQ%),BQ%)=FT%
  2059.         Q%=BQ%:GoSub TOP-LINE 
  2060.         BQ%=BQ%+1:DQ%=BQ%
  2061.     else when MID$(XLINE.$,I%+1,1)=EQUATE$
  2062.         MK$=MID$(XLINE.$,I%+2,1):XLINE.$=BLANK$
  2063.     else when MID$(XLINE.$,I%+1,1)=TABS$
  2064.         TB%=val(MID$(XLINE.$,I%+2,1)):XLINE.$=BLANK$
  2065.     endw
  2066. endp
  2067. proc BOTTOM-FRAME
  2068.     Q%=IK%:FT%=MK%(I%,IK%)
  2069.     GoSub BOTTOM-LINE
  2070.     MK%(I%,IK%)=-1:BQ%=BQ%-1
  2071. endp
  2072. proc TOP-LINE
  2073.     GoSub LINE-LENGTH
  2074.     B%=BL%(Q%):E%=EL%(Q%)
  2075.     $insert B%,TLC%(FT%)
  2076.     GoSub TOPS-BOTTOMS
  2077.     $insert E%,TRC%(FT%)
  2078. endp
  2079. proc BOTTOM-LINE
  2080.     GoSub LINE-LENGTH
  2081.     B%=BL%(Q%):E%=EL%(Q%)
  2082.     $insert B%,BLC%(FT%)
  2083.     GoSub TOPS-BOTTOMS
  2084.     $insert E%,BRC%(FT%)
  2085. endp
  2086. proc TOPS-BOTTOMS
  2087.     B%=B%+1
  2088.     while B%<E%
  2089.         $insert B%,HL%(FT%)
  2090.         B%=B%+1
  2091.     wend
  2092. endp
  2093. proc INSERT-SIDES
  2094.     IF(INSTR(XLINE.$,CHR$(9)))THEN GoSub REMOVE-TABS
  2095.     GoSub LINE-LENGTH
  2096.     J%=0
  2097.     while J%<BQ%è        FT%=MK%(BL%(J%),J%)
  2098.         when FT%>-1
  2099.             $insert BL%(J%),VL%(FT%)
  2100.             $insert EL%(J%),VL%(FT%)
  2101.         endw
  2102.         J%=J%+1
  2103.     wend
  2104. endp
  2105. proc LINE-LENGTH
  2106.     unless LEN(XLINE.$)=>EK%
  2107.         XLINE.$=XLINE.$+STRING$(EK%-LEN(XLINE.$)+1,32)
  2108.     endu
  2109. endp
  2110. proc REMOVE-TABS
  2111.     T%=INSTR(1,XLINE.$,CHR$(9))
  2112.     while T%>0
  2113.         L$=LEFT$(XLINE.$,T%-1)
  2114.         R$=RIGHT$(XLINE.$,LEN(XLINE.$)-T%)
  2115.         XLINE.$=L$+STRING$(TB%,32)+R$
  2116.         T%=INSTR(1,XLINE.$,CHR$(9))
  2117.     wend
  2118. endp
  2119. proc INSERT-BLOCK
  2120.     unless BK%=0
  2121.         when MID$(XLINE.$,BK%,1)=" " or MID$(XLINE.$,BK%,1)=MK$
  2122.             MID$(XLINE.$,BK%,1)=CHR$(CK%)
  2123.         endw
  2124.     endu
  2125. endp
  2126. '┌────────────────────────────────────────────────────┐
  2127. '│ ** Sub-Routine Division                            │
  2128. '└────────────────────────────────────────────────────┘
  2129.  
  2130.  
  2131. XFRAME.ML
  2132.  
  2133. ;;==========================================================================
  2134. ; NOTE:
  2135. ;         THE `|' VERTICAL BAR IS USED AS A CONTINUATION MARK.
  2136. ; DOCUMENTATION ABREVIATIONS:
  2137. ;         S/L  =  STRING VARIABLE OR LITERAL ENCLOSED WITH DOUBLE QUOTES.
  2138. ;         N/L  =  NUMERIC VARIABLE OR LITERAL.
  2139. ;         S    =  STRING VARIABLE ONLY.
  2140. ;         N    =  NUMERIC VARIABLE ONLY.         
  2141. ;         S/N  =  STRING OR NUMERIC VARIABLE.
  2142. ;         
  2143. ;;==========================================================================
  2144. ;**
  2145. ::LOOKUP (Macro)
  2146. ;**   FUNCTION:
  2147. ;**             Verify the existence of a file.
  2148. ;**   USAGE:
  2149. ;**             Two parameters required.
  2150. ;**     Calling:
  2151. ;**             [1] - S/L - a valid file name.è;**             [2] - N   - a valid file number (>0).
  2152. ;**     Returning:
  2153. ;**             [2] - zero if file not found.
  2154. ;**   EXAMPLE:
  2155. ;**             TXT% = 2
  2156. ;**             $lookup "myfile.txt",TXT%
  2157. ;**                       (if "myfile.txt" is not found then TXT% = 0.)
  2158. ;**             $lookup MYFILE$,TXT%
  2159. ;**
  2160. MACRO LOOKUP
  2161.    XX.$=[1]:XX.%=[2]:Gosub _Lookup:[2]=XX.%
  2162.    $$_LOOKUP
  2163. ENDM
  2164. ;;==========================================================================
  2165. ;**
  2166. ::_LOOKUP (Subroutine)
  2167. ;**   FUNCTION:
  2168. ;**             Subroutine called by LOOKUP macro.
  2169. ;**
  2170. MACRO _LOOKUP
  2171. Proc _Lookup
  2172.    Open"R",XX.%,XX.$:X.X!=LOF(XX.%):Close XX.%|
  2173.    IF(X.X!<1)Then XX.%=0:Kill XX.$
  2174. Endp
  2175. ENDM
  2176. ;;==========================================================================
  2177. ;**
  2178. ::OPENFI (Macro)
  2179. ;**   FUNCTION:
  2180. ;**             Open a file for input.
  2181. ;**   USAGE:
  2182. ;**             Two parameters required.
  2183. ;**     Calling:
  2184. ;**             [1] - S/L - valid file name.
  2185. ;**             [2] - N/L - valid file number.
  2186. ;**   EXAMPLE:
  2187. ;**             $openfi "myfile.txt",2
  2188. ;**             $openfi MYFILE$,MYFILE%
  2189. ;**             
  2190. MACRO OPENFI
  2191.    Open"I",[2],[1]
  2192. ENDM
  2193. ;;==========================================================================
  2194. ;**
  2195. ::OPENFO (Macro)
  2196. ;**   FUNCTION:
  2197. ;**             Open a file for output.
  2198. ;**   USAGE:
  2199. ;**             Two parameters required.
  2200. ;**     Calling:
  2201. ;**             [1] - S/L - valid file name.
  2202. ;**             [2] - N/L - valid file number.
  2203. ;**   EXAMPLE:
  2204. ;**             $openfo "myfile.txt",2
  2205. ;**             $openfo MYFILE$,MYFILE%è;**             
  2206. MACRO OPENFO
  2207.    Open"O",[2],[1]
  2208. ENDM
  2209. ;;==========================================================================
  2210. ;**
  2211. ::LINPUT (Macro)
  2212. ;**   FUNCTION:
  2213. ;**             Input a line from a file open for input.
  2214. ;**   USAGE:
  2215. ;**             Two parameters required.
  2216. ;**     Calling:
  2217. ;**             [1] - N/L - valid file number.
  2218. ;**     Returning:
  2219. ;**             [2] - S   - string buffer.
  2220. ;**   EXAMPLE:
  2221. ;**             $linput 2,BUFFER$
  2222. ;**             $linput BUF%,BUFFER$
  2223. ;**             
  2224. MACRO LINPUT
  2225.    Line Input #[1],[2]
  2226. ENDM
  2227. ;;==========================================================================